Axios returns network error when request fails with a 429 status code
srbadni opened this issue · comments
Describe the issue
I tried to handle status 429 in the response interceptor, but the error object's code is "ERR_NETWORK".
Example Code
http.interceptors.response.use((response) => {
if (response.data.errors?.length) {
response.data.errors.map((error: ErrorType) => {
store.dispatch(callErrorToast(error.message));
});
}
return response
},
async (err) => {
if (err.response.status === 429) {
//do something
}
return Promise.reject(err);
}
)
but err value is :
{
"message": "Network Error",
"name": "AxiosError",
.
.
.
"code": "ERR_NETWORK"
}
### Expected behavior
I need access to status 429
### Axios Version
1.7.8
### Adapter Version
xhr/http/fetch
### Browser
Chrome
### Browser Version
_No response_
### Node.js Version
_No response_
### OS
_No response_
### Additional Library Versions
```bash
react 18
next 14
Additional context/Screenshots
No response
Thank you for reporting this issue, @srbadni! Let me address the problem and clarify the behavior.
Understanding the Issue
The ERR_NETWORK code in the AxiosError object indicates that the request failed due to a network error, rather than receiving a valid HTTP response. This can happen if:
The browser blocked the request due to CORS issues.
The network request was interrupted or failed to reach the server.
The server did not provide a valid HTTP response.
In your case, it seems you're trying to handle status 429 (Too Many Requests) in the response interceptor, but the request never reaches a point where Axios receives the response from the server. Instead, Axios treats the situation as a network error.
Why This Happens
Axios relies on adapters (e.g., xhr, http, fetch) to handle network requests. When the adapter encounters certain conditions—like a CORS violation or a server disconnect—it cannot parse the server's response and instead throws an error with the code: "ERR_NETWORK".
Debugging and Resolution
Here are some steps to investigate and resolve the issue:
Check CORS Settings: If your server's response is blocked by the browser (e.g., due to missing or misconfigured CORS headers), Axios will report a network error. Ensure the server allows the necessary CORS headers:
Access-Control-Allow-Origin: *
Access-Control-Allow-Headers: Content-Type
Access-Control-Allow-Methods: GET, POST, OPTIONS, PUT, DELETE
Inspect the Network Tab: Use your browser's DevTools (Network tab) to inspect the actual request and response. Verify:
Is the server returning a status 429?
Is the response visible, or does the request fail due to CORS or a timeout?
Ensure the Server Returns a Proper Response: Confirm that the server returns the 429 Too Many Requests status with a valid HTTP response. If the response is malformed or missing headers, Axios might misinterpret it as a network error.
Enable Axios Debugging: Use Axios's debug capabilities to get more details about the request:
axios.interceptors.request.use((config) => {
console.log('Request:', config);
return config;
});
axios.interceptors.response.use(
(response) => {
console.log('Response:', response);
return response;
},
(error) => {
console.error('Error:', error);
return Promise.reject(error);
}
);
Handle Specific Errors Gracefully: If the server sends back a 429 response but it’s being handled incorrectly as a network error, you can add a retry mechanism or log additional context.
Possible Workaround
To ensure you capture 429 errors properly, you can handle ERR_NETWORK errors by examining the raw error object. While this is not ideal, it can provide insight into what’s happening:
axios.interceptors.response.use(
(response) => {
return response;
},
async (err) => {
if (err.response?.status === 429) {
// Handle 429 status
} else if (err.code === "ERR_NETWORK") {
console.error("Network error occurred:", err.message);
// Additional logic for network errors
}
return Promise.reject(err);
}
);
Recommendations for Axios Team
If this behavior is caused by an underlying issue in Axios's handling of responses for status codes like 429, consider:
Enhancing the error handling to distinguish between true network errors and valid HTTP responses that cannot be parsed.
Providing more detailed documentation or examples for handling 429 and other edge cases.
Thank you again for your report, and I hope this helps clarify the issue! If you find anything further during debugging, please share so we can investigate further.
@Ehteshamali1109, so, in the scenario where I'm facing a 403 from the Gateway WAF (I can see it in the browser dev tools or postman) and no response property on the error variable from .catch
is there any way to get either the status (403) or more information about how to differentiate what the error is?
Thank you for your question, @FedeMM! It seems you're encountering a scenario where the request fails with a 403 Forbidden response from the Gateway WAF, but Axios does not provide the response property in the error object. This can happen if the error is caused by a network issue or if Axios's underlying adapter cannot parse the server's response.
Here’s how you can approach this issue:
Understanding the Problem
When Axios throws an error, it provides an error object that includes:
response: Contains the HTTP response (if the server sends one).
request: The raw XMLHttpRequest or HTTP request object (if applicable).
code: An error code like ERR_NETWORK (for network issues).
message: A human-readable description of the error.
In your case, the lack of a response object means Axios couldn't parse the server's response. Common causes include:
CORS Restrictions: The browser blocked the response before Axios could process it.
Malformed Response: The server's response did not follow HTTP standards.
Adapter Limitations: The Axios adapter (e.g., xhr or fetch) could not access the response due to environmental constraints.
Debugging Steps
To gain more insight into the problem:
Inspect Network Traffic:
Use browser dev tools (Network tab) or tools like Postman to confirm the server is sending a 403 response.
Check if the response includes unusual headers or a body that might trigger issues.
Check CORS Configuration (for browser environments):
Ensure the server includes the necessary CORS headers in the response:
Access-Control-Allow-Origin: *
Access-Control-Allow-Headers: Content-Type
Access-Control-Allow-Methods: GET, POST, OPTIONS, PUT, DELETE
Enable Axios Debugging: Log detailed request and error information:
axios.interceptors.request.use((config) => {
console.log('Request Config:', config);
return config;
});
axios.interceptors.response.use(
(response) => response,
(error) => {
console.error('Error Details:', error);
return Promise.reject(error);
}
);
Possible Workarounds
If you still can’t access the response object, consider the following:
- Analyze Raw Errors
Use the error.request property, which contains the raw request details. While it doesn’t include the status code, it might reveal why the error occurred:
axios.interceptors.response.use(
(response) => response,
(error) => {
if (error.code === 'ERR_NETWORK' && error.request) {
console.error('Network issue:', error.message);
} else if (!error.response) {
console.error('Error without response:', error.message);
}
return Promise.reject(error);
}
);
- Fetch with XMLHttpRequest or fetch
Sometimes using XMLHttpRequest or fetch directly can expose more details:
fetch(url, options)
.then((response) => {
if (response.status === 403) {
console.error('403 Forbidden detected');
}
return response.json();
})
.catch((err) => {
console.error('Fetch Error:', err);
});
- Gateway WAF Configuration
If you have access to the Gateway/WAF, verify its configuration to ensure it doesn't block necessary headers or responses.
Recommendations for Axios Team
As you pointed out, improving error handling in cases where the server returns an HTTP status (like 403) but the response is inaccessible could help developers diagnose issues more effectively. For instance:
Providing additional metadata (e.g., raw status codes) in error.request.
Documenting best practices for handling such scenarios.
it show error some time 404 and sometime 401 when I test the API with postman then it was working fine and then I use the simple fetch method then start working