【问题标题】:Handling HTTP error with async await and try and catch clause in react typescript在反应打字稿中使用异步等待和 try 和 catch 子句处理 HTTP 错误
【发布时间】:2022-01-11 08:11:55
【问题描述】:

我有以下代码!

import React, { useState } from "react";

function App() {
const [movies, setMovies] = useState([]);
  const [isLoading, setIsLoading] = useState(false);
  const [error, setError] = useState<string | null>();
 async function fetchMoviesHandler() {
    setIsLoading(true);
    setError(null);
try {
      const response = await fetch("https://swapi.dev/api/film/");

      const data = await response.json();
const transformedMovies = data.results.map((movieData: any) => {
        return {
          id: movieData.episode_id,
          title: movieData.title,
          openingText: movieData.opening_crawl,
          releaseDate: movieData.release_date,
        };
      });
setMovies(transformedMovies);
} catch (err: any) {
setError(err.Message);
      console.log(err);
    }
    setIsLoading(false);
  }
return (
    <React.Fragment>
      <section>
        <button onClick={fetchMoviesHandler}>Fetch Movies</button>
      </section>
      <section>
        
        {!isLoading && movies.length > 0 && <p>Movies fetched!</p>}
        {!isLoading && movies.length === 0 && !error && <p>Found no movies.</p>}
        {!isLoading && error && <p>{error}</p>}
        {isLoading && <p>Loading...</p>}
      </section>
    </React.Fragment>
  );
}

export default App;

这里的 URL 不正确,会抛出 404 错误,我希望显示该错误消息。当我 console.log 错误消息显示在控制台上,但错误消息未显示在网页上。如果有人可以帮助我解决这个问题,将不胜感激。

【问题讨论】:

    标签: reactjs typescript async-await try-catch http-error


    【解决方案1】:

    Fetch docs可以看到:

    从 fetch() 返回的 Promise 不会拒绝 HTTP 错误状态 即使响应是 HTTP 404 或 500。而是 [...] Promise 将正常解析(将响应的 ok 属性设置为 如果响应不在 200–299 范围内,则返回 false)

    所以fetchMoviesHandler 中的catch 子句在收到 404 响应时不会立即执行,它只会在您尝试从响应 (const data = await response.json()) 解析正文时执行,因为没有 json 可用于在那里解析。那是错误实际上被抛出和捕获的时候,但是它上面没有 Message 属性,所以没有什么可显示的:内置错误对象上的属性是 message

    为了处理这种情况,您应该检查 HTTP 响应中的 ok 属性并抛出特定错误。像这样的:

    async function fetchMoviesHandler() {
        setIsLoading(true);
        setError(null);
        try {
          const response = await fetch('https://swapi.dev/api/film/');
          if (!response.ok) {
            throw new Error('Something went wrong');
          }
          const data = await response.json();
          const transformedMovies = data.results.map((movieData: any) => {
            return {
              id: movieData.episode_id,
              title: movieData.title,
              openingText: movieData.opening_crawl,
              releaseDate: movieData.release_date,
            };
          });
          setMovies(transformedMovies);
        } catch (err: any) {
          setError(err.message);
          console.log(err);
        }
        setIsLoading(false);
      }
    

    【讨论】:

    • 嗨。谢谢。似乎问题出在“err.Message”上,而应该是“err.message”。它在没有 if (!response.ok) 的情况下工作,因为我正在做一个 try catch 子句,所以当出现错误时它实际上会移动到 catch 子句。但似乎内置的 err.message 应该是那里调用的那个。我实际上是从您的回答中得到的。再次感谢,如果可能,请编辑答案,我会将您的答案标记为正确的。
    • @kevinTHEprogrammer 我添加了对message 属性的提及,但我会坚持我的其余答案(尽管不要接受它)。当然,如果发生错误,您会转到 catch 子句,但关键是您没有捕获您应该捕获的错误。您正在捕获解析错误,而不是 404。在您的情况下这可能没问题,但通常不是:例如服务器可能会使用可解析的 JSON 发回 400 响应,那么您将不会有任何解析错误(映射结果时可能会出现不同的错误)。答案的重点是:专门处理错误。
    • 谢谢。这很清楚。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-02-11
    • 1970-01-01
    • 2017-06-08
    • 2016-01-26
    • 2018-12-20
    相关资源
    最近更新 更多