使用 Async/Await 处理 404 错误响应

Handling 404 Error Response with Async/Await

我正在开发一个天气应用程序,需要正确处理来自服务器的 404 响应。有 2 个 API 请求,第二个请求需要第一个请求的数据。

我基本上想在出现 404 错误响应时呈现“位置不存在”。尝试 try..catch 导致了这个问题:Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'coord').

成功和失败响应都会出错。

问题:

这是包含逻辑和 API 调用的 useForecast.js 文件:

import axios from "axios";

const BASE_URL = "https://api.openweathermap.org/data/2.5";
const API_KEY = process.env.REACT_APP_API_KEY;

const useForecast = () => {
  // const [forecast, setForecast] = useState(null)
  // const [isError, setError] = useState(false)

  const getCoordinates = async (location) => {
    try {
      //try statement
      const { data } = await axios(`${BASE_URL}/weather`, {
        params: { q: location.value, appid: API_KEY }
      });
      console.log("call is successful", data);
    } catch (data) {
      //catch statement
      if (!data.ok) {
        console.log("location does not exist", data.message);
        return;
      }
      return data;
    }
  };

  const getForecastData = async (lat, lon) => {
    const { data } = await axios(`${BASE_URL}/onecall`, {
      params: { lat: lat, lon: lon, appid: API_KEY }
    });

    //if no data is not returned, call setError("Something went wrong") and return

    return data;
  };

  const submitRequest = async (location) => {
    const response = await getCoordinates(location);
    const { lat, lon } = response.coord;

    if (!response || !lat || !lon) return;
    console.log("getCoordinates call will render", { response });

    const data = await getForecastData(lat, lon);
    if (!data) return;
    console.log("getForecastData call will render", { data });
  };

  return {
    submitRequest
  };
};

export default useForecast;

这是该应用程序的精简版(其中生成屏幕截图):https://codesandbox.io/s/practical-pare-uc65ee?file=/src/useForecast.js

注意: API 密钥已出于隐私原因删除(对于给您带来的不便,我们深表歉意)

最后,对于上下文,我在应用程序中使用 React:

您已成功捕获错误。问题是当它发生时,你没有返回任何值给

const response = await getCoordinates(location);

response 将是未定义的,因此 coord 将触发错误,因为 undefined 值不能包含任何 属性.

要修复它,您可以使用下面的经典安全:

const response = await getCoordinates(location) || {};

这基本上将使 response 始终是一个对象,无论成功与否

除了@Houssam 和@ale917k 的建议外,还必须对 submitRequest 中的条件进行调整。

所做的所有调整是:

  1. return data 放在 try 块内
  2. || {} 附加到响应中
  3. 首先将 if 语句更改为 if(!response.coord),然后 de-structure 纬度和经度。

有变化的代码库:

import axios from "axios";

const BASE_URL = "https://api.openweathermap.org/data/2.5";
const API_KEY = process.env.REACT_APP_API_KEY;

const useForecast = () => {
  // const [forecast, setForecast] = useState(null)
  // const [isError, setError] = useState(false)

  const getCoordinates = async (location) => {
    try {
      const { data } = await axios(`${BASE_URL}/weather`, {
        params: { q: location.value, appid: API_KEY }
      });
      console.log("call is successful", data);
      //adjustment 1
      return data;
    } catch (data) {
      if (!data.ok) {
        console.log("location does not exist");
        return;
      }
    }
  };

  const getForecastData = async (lat, lon) => {
    try {
      const { data } = await axios(`${BASE_URL}/onecall`, {
        params: { lat: lat, lon: lon, appid: API_KEY }
      });
      return data;
    } catch (data) {
      if (!data.ok) {
        console.log("something went wrong");
        return;
      }
    }
  };

  const submitRequest = async (location) => {
    const response = (await getCoordinates(location)) || {}; //adjustment 2
    //adjustment 3
    if (!response.coord) return;

    const { lat, lon } = response.coord;
    const data = await getForecastData(lat, lon);

    if (!data) return;
  };

  return {
    submitRequest
  };
};

export default useForecast;

成功和失败日志截图: