React中OpenWeatherMap API无效输入触发400错误致应用崩溃问题
Hey there! I’ve run into this exact issue with OpenWeatherMap’s API before—let’s get your app stopped from crashing when users mistype city names. The core problem is that when the API can’t find the requested city, it returns a non-success status code (like 404), but your code is probably trying to access properties from the response without first verifying if the data exists. Here’s how to fix it:
1. Add Proper Error Checking to Your API Request
Unlike some libraries, fetch doesn’t automatically throw an error for non-2xx status codes. So you need to manually check if the response is valid before parsing the JSON. Here’s how to update your API call:
// Inside your method that handles the city search fetch(`https://api.openweathermap.org/data/2.5/weather?q=${userInputCity}&appid=${YOUR_API_KEY}`) .then(response => { // Check if the response is successful (status 200-299) if (!response.ok) { throw new Error("Oops! That city doesn't exist. Please double-check the spelling."); } return response.json(); }) .then(data => { // Only update state with valid weather data here this.setState({ temperature: Math.round(data.main.temp - 273.15), // Convert Kelvin to Celsius city: data.name, humidity: data.main.humidity, description: data.weather[0].description, icon: `http://openweathermap.org/img/w/${data.weather[0].icon}.png`, error: undefined // Clear any previous error messages }); }) .catch(error => { // Update state with the error instead of letting the app crash this.setState({ temperature: undefined, city: undefined, humidity: undefined, description: undefined, icon: undefined, error: error.message }); });
2. Update Your Render Logic to Handle Errors
Now, in your render method, you need to check if there’s an error in the state and display it instead of trying to render weather data that doesn’t exist:
render() { const { temperature, city, humidity, description, icon, error } = this.state; return ( <div className="weather-app"> {/* Display error message if it exists */} {error && <div className="error-alert">*{error}*</div>} {/* Only display weather info if city data exists */} {city && ( <div className="weather-card"> <h2>Current Weather in {city}</h2> <img src={icon} alt={description} className="weather-icon" /> <p className="temp">{temperature}°C</p> <p>Humidity: {humidity}%</p> <p>Condition: {description.charAt(0).toUpperCase() + description.slice(1)}</p> </div> )} {/* Your city input form goes here */} </div> ); }
Quick Tips to Avoid Future Crashes:
- Always validate API responses before accessing nested properties (like
data.weather[0].description—what ifweatheris empty? You could add an extra check here too!) - Reset all weather-related state properties in the
catchblock so your render method doesn’t try to access undefined values. - Use descriptive error messages to help users correct their input (instead of a generic "error" message).
内容的提问来源于stack exchange,提问作者llievredemars

