React
Handling Errors in API Calls
Day 19
Why Error Handling Matters
API calls can fail due to network issues
or server errors.
Unhandled errors can crash applications
or break UI functionality.
Proper error handling improves user
experience and debugging.
Helps display meaningful messages
instead of broken UI.
Prevents performance issues caused by
unnecessary re-renders.
Using Try/Catch for Error Handling
try/catch blocks catch API call failures and
prevent crashes.
async function fetchData() {
try {
let response = await
fetch("https://jsonplaceholder.typicode.com/posts");
if (!response.ok) throw new Error("Network
error");
let data = await response.json();
console.log(data);
} catch (error) {
console.error("Error fetching data:",
error.message);
}
}
fetchData();
Handling Errors with Axios
Axios automatically rejects failed requests,
making error handling easier.
axios.get("https://jsonplaceholder.typicode.com/posts
")
.then(response => console.log(response.data))
.catch(error => console.error("Error fetching
data:", error.message));
Displaying Errors in React Components
Use state to show error messages in the UI.
import { useState, useEffect } from "react";
import axios from "axios";
function DataComponent() {
const [data, setData] = useState([]);
const [error, setError] = useState(null);
useEffect(() => {
axios.get("https://jsonplaceholder.typicode.com/posts
")
.then(response => setData(response.data))
.catch(error => setError("Failed to load
data"));
}, []);
return (
<div>
{error ? <p>{error}</p> : <ul>{data.map(item =>
<li key={item.id}>{item.title}</li>)}</ul>}
</div>
);
}
export default DataComponent;
Using Error Boundaries in React
Error boundaries catch JavaScript errors in
React components.
They prevent the entire app from crashing
due to a component failure.
import { Component } from "react";
class ErrorBoundary extends Component {
constructor(props) {
super(props);
this.state = { hasError: false };
}
static getDerivedStateFromError() {
return { hasError: true };
}
componentDidCatch(error, info) {
console.error("Error caught:", error, info);
}
render() {
if (this.state.hasError) return <h2>Something
went wrong.</h2>;
return this.props.children;
}
}
export default ErrorBoundary;
Handling Different Types of Errors
Network Errors: Occur when there is no
internet connection.
Server Errors: Happen when the backend
returns a 500 or similar status.
Client Errors: Caused by invalid input or
incorrect requests.
Timeout Errors: Occur when the API takes
too long to respond.
Parsing Errors: Happen when the response is
not valid JSON.
axios.get("https://jsonplaceholder.typicode
.com/posts")
.catch(error => {
if (error.response)
console.error("Server Error:",
error.response.status);
else if (error.request)
console.error("Network Error: No response
received");
else console.error("Request Error:",
error.message);
});
Retrying Failed API Calls
Some errors are temporary and can be
retried automatically.
Retry logic helps improve user experience in
case of failures.
async function fetchDataWithRetry(url, retries = 3) {
for (let attempt = 1; attempt <= retries;
attempt++) {
try {
let response = await fetch(url);
if (!response.ok) throw new Error("Server
error");
return await response.json();
} catch (error) {
console.error(`Attempt ${attempt} failed:`,
error.message);
if (attempt === retries) throw error;
}
}
}
fetchDataWithRetry("https://jsonplaceholder.typicode.
com/posts")
.then(data => console.log(data))
.catch(() => console.error("All attempts failed"));
Best Practices for Handling API Errors
Always wrap API calls inside try/catch to
prevent crashes.
Show meaningful error messages instead of
generic alerts.
Use error boundaries to prevent app-wide
crashes.
Implement retry logic for temporary failures.
Use loading indicators to improve user
experience.
Log errors for debugging but avoid exposing
server details to users.
Handle different types of errors separately
for better debugging.