抛出错误消息没有被 catch 方法捕获

时间:2021-04-23 22:04:50

标签: javascript reactjs react-hooks

我正在学习有关处理 YouTube 上的提取错误的 React 教程。我完全按照教员的做法做了,但由于某种原因,catch 方法没有捕获 throw 错误消息。代码如下:

const Home = () => {
  const [blogs, setBlogs] = useState(null);
  const [isPending, setIsPending] = useState(true);
  const [error, setError] = useState(null);

  useEffect(() => {
    setTimeout(() => {
      fetch("http://localhost:8000/blogs")
        .then((res) => {
          if (!res.ok) {
            throw Error("This error is not getting caught");
          }
          return res.json();
        })
        .then((data) => {
          setBlogs(data);
          setIsPending(false);
          setError(null);
        })
        .catch((err) => {
          setIsPending(false);
          setError(err.message);
        });
    }, 1000);
  }, []);

  return (
    <div className="home">
      {error && <div>{error} </div>}
      {isPending && <div>Loading...</div>}
      {blogs && <BlogList blogs={blogs} title="All Blogs!" />}
    </div>
  );
};

export default Home;

注意:服务器没有运行。

1 个答案:

答案 0 :(得分:5)

当收到响应标头时,.then 中的第一个 fetch 将被输入。响应标头可能表明存在问题 - 如果响应不是 .ok - 在这种情况下,您的 throw Error 将根据需要输入并将控制流向下发送到较低的 .catch .

但是如果根本没有收到响应头,第一个 .then不会被输入 - 相反,网络错误将导致拒绝和下面的 .catch将直接进入。

您的代码导致显示 Failed to fetch,因为这是来自失败请求的错误消息,甚至没有返回任何标头:

const { useState, useEffect } = React;
const Home = () => {
  const [blogs, setBlogs] = useState(null);
  const [isPending, setIsPending] = useState(true);
  const [error, setError] = useState(null);

  useEffect(() => {
    setTimeout(() => {
      fetch("http://localhost:8000/blogs")
        .then((res) => {
          if (!res.ok) {
            throw Error("This error is not getting caught");
          }
          return res.json();
        })
        .then((data) => {
          setBlogs(data);
          setIsPending(false);
          setError(null);
        })
        .catch((err) => {
          setIsPending(false);
          setError(err.message);
        });
    }, 1000);
  }, []);

  return (
    <div className="home">
      {error && <div>{error} </div>}
      {isPending && <div>Loading...</div>}
      {blogs && <BlogList blogs={blogs} title="All Blogs!" />}
    </div>
  );
};

ReactDOM.render(<Home />, document.querySelector('.react'));
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<div class='react'></div>

如果您也希望在这种情况下显示 This error is not getting caught,请更改

setError(err.message);

setError('This error is not getting caught');