使用 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')
.
成功和失败响应都会出错。
问题:
- 这个错误是什么意思,我怎样才能正确地解构
coord
道具?
- 如何正确设置 try..catch 以处理错误响应?
- 额外的问题:如何在
getForecastData
函数中创建 try..catch?
这是包含逻辑和 API 调用的 useForecast.js 文件:
- try...catch 尝试在
getCoordinates
函数中进行
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:
- OpenWeather API: https://openweathermap.org/
- Axios:https://github.com/axios/axios
您已成功捕获错误。问题是当它发生时,你没有返回任何值给
const response = await getCoordinates(location);
response
将是未定义的,因此 coord
将触发错误,因为 undefined
值不能包含任何 属性.
要修复它,您可以使用下面的经典安全:
const response = await getCoordinates(location) || {};
这基本上将使 response
始终是一个对象,无论成功与否
除了@Houssam 和@ale917k 的建议外,还必须对 submitRequest
中的条件进行调整。
所做的所有调整是:
- 将
return data
放在 try
块内
- 将
|| {}
附加到响应中
- 首先将 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;
成功和失败日志截图:
我正在开发一个天气应用程序,需要正确处理来自服务器的 404 响应。有 2 个 API 请求,第二个请求需要第一个请求的数据。
我基本上想在出现 404 错误响应时呈现“位置不存在”。尝试 try..catch 导致了这个问题:Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'coord')
.
成功和失败响应都会出错。
问题:
- 这个错误是什么意思,我怎样才能正确地解构
coord
道具? - 如何正确设置 try..catch 以处理错误响应?
- 额外的问题:如何在
getForecastData
函数中创建 try..catch?
这是包含逻辑和 API 调用的 useForecast.js 文件:
- try...catch 尝试在
getCoordinates
函数中进行
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:
- OpenWeather API: https://openweathermap.org/
- Axios:https://github.com/axios/axios
您已成功捕获错误。问题是当它发生时,你没有返回任何值给
const response = await getCoordinates(location);
response
将是未定义的,因此 coord
将触发错误,因为 undefined
值不能包含任何 属性.
要修复它,您可以使用下面的经典安全:
const response = await getCoordinates(location) || {};
这基本上将使 response
始终是一个对象,无论成功与否
除了@Houssam 和@ale917k 的建议外,还必须对 submitRequest
中的条件进行调整。
所做的所有调整是:
- 将
return data
放在try
块内 - 将
|| {}
附加到响应中 - 首先将 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;
成功和失败日志截图: