When making a request via axios that has an error response (according to axios docu any status outside of 2xx) the corresponding request method throws an error.
Not wanting to surround each and every request I make with generic catch blocks I finally figured out how to "get around" this with an interceptor:
$axios.onError((error) => {
return Promise.resolve(error);
})
probably corresponds to:
axios.interceptors.response.use(function (error) {
return Promise.resolve(error);
});
in vanilla axios.
My current question is: Is this considered to be bad practice? Is there a better way to to this? (Maybe something involving a config setting for validateStatus?) Also, since the status 2xx is explicitly stated I wonder whether also 1xx would throw an error.
The thrown error is especially unnerving because nuxt redirects to the error page every time I don't catch the error... So any help regarding that behaviour would be welcome too.
Related
Just a curiosity question, for the package axios in javascript, node or otherwise, the default setting is to throw an error for any response 400 or greater (not sure if that's exactly right but meh). I have previously been taught that using catch where a if statement could have worked fine is generally considered bad practice. To get to my question, in circumstances where 404 errors are expected fairly frequently, would it be better to use a if statement instead of a catch (for the package axios this means moving away from the default settings using validateStatus)?
Things to consider, does being on AWS lambda change anything? Is it different for different node versions or JavaScript versions/browsers?
Any insight appreciated :)
Axios is not by any noticeable means slower than fetch. The tradeoffs between using Axios or handling your own raw http requests is not worth it for many developers.
Check out Axios Interceptors. It lets you deal with requests and responses before they're handled in the then or catch blocks.
axios.interceptors.request.use((req) => {
return req;
});
axios.interceptors.response.use(
(res) => res,
(err) => {
if (err?.response?.status != null) {
console.log(`Intercepted status: ${err.response.status}`);
} else {
console.log(
`No response from server, using request status`,
err.request.status
);
}
return Promise.reject(err);
}
);
Here's an example sandbox I put together recently showing interceptors in-action.
There's no concern with using Axios on AWS Lambda. The newer versions of Axios would not work with old Node.js versions but it's very dependent on the package version. Generally not something to worry about.
I am using fetch and it is to my understanding that 404 codes should happen but not GET 404 errors when fetching from a non existent page. I am using the open weather map api. The error that I'm getting is GET ${forcastUrl} 404 (Not Found).
My fetch statement looks like this:
function fetchingForcast(forcastUrl){
fetch(forcastUrl)
.then(validateWeatherResponse)
.then(responseToJSON)
.then(dat => {
forcastDat = dat;
updateforcastPanel();
})
.catch(error=>{
console.log(error);
})
}
function validateWeatherResponse(response){
if (response.ok){
return response;
} else {
throw Error("response.ok: "+ response.ok);
}
validateWeatherResponse checks if the response is ok and if not, it throws an error. However, when it does throw an error, it should go to catch and console.log the error. When I use the debug devtool on chrome, the error appears to happen as soon as validateWeatherResponse is called.
Besides for this error, my code works when I input a correct website. It is to my understanding that 404 errors should not occur so I'd like to understand why this is happening.
Thanks!
From MDN's HTTP status code documentation:
404 Not Found
The server can not find the requested resource. In the browser, this means the URL is not recognized. In an API, this can also mean that the endpoint is valid but the resource itself does not exist. This response code is probably the most famous one due to its frequent occurrence on the web.
The 404 error code means that the website or endpoint that you requested does not exist, which is definitely expected if you request a non-existent page.
If you are still confused about the error, please tell me in a comment.
I'd like to be able to read what the request method of my axios API call is when I am catching an error due to a bad request. Basically, I need to be able to handle errors differently depending on if the request method is of type GET vs type POST/PUT.
I see that the Fetch API has a method that would give the behaviour that's similar to what I'm looking for, like this here
Thanks for all help.
I answered my own question. Pass your callback in the catch clause as you normally would, and define error as the first parameter.
The request method type is accessible in the axios catch block via: error.response.config.method
I'm aware that fetch api will either go into catch or return with response.ok as false. In my case, (I believe) we consistently get to catch statement in our code and I'm trying to figure out what might be the issue.
Just to specify, fetch I'm talking about:
https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API
While there are a lot of answers in regards to how one should also pay attention to checking response.ok, there is not much answers for what might cause the fetch to go into catch statement.
We specifically get the error as Error: TypeError: Failed to fetch
Some of the reasons I've seen online for going to catch statement are:
Access-Control-Allow-Origin not matching
connection error?
timeout?
Thanks
Edit: I just realized this is a duplicate of Recommended solution for AJAX, CORS, Chrome & HTTP error codes (401,403,404,500), and he tried the idea I propose at the end. But I can't tell if he succeeded (dud user?), and no one else has posted a solution or even a comment, so I think it's worth fishing for new answers.
Problem:
I send a properly-executed (edit: IMproperly-executed. End of story...) CORS request.
The server receives the request and attempts to process it.
The server returns an error response, for example a 422 Unprocessable Entity, along with JSON information about the errors. The idea is that my app could receive this error information and handle it appropriately in the UI.
The browser blocks my error handler from getting the response content, or even getting the status code.
Showing that the browser received the 401 status code but treated it as a CORS security error:
The response object, showing that my code cannot access the response data (data: "", status: 0):
How have other people handled this limitation? My best guess right now is to hijack an HTTP "success" code (2XX) as an error code, and then include the error information in the response. This prevents me from using the ajax error handlers in a normal way, but I'm handling this as a global ajax filter anyway, so this filter would capture the deviant success code and trigger the error handlers instead.
The console message indicates that the server isn't sending the required Access-Control-Allow-Origin header when it sends the 401 response code.
You won't be able to use the CORS error handler to inject content into the DOM unless you fix that.
The server is likely sending the header correctly on responses with a 200 response code. It needs to do it for other response codes, though, if you wish to use data from those response codes.
Fix that on the server end before making design compromises on the client side. That may solve your problem straight away.
It seems it's an opaque response where you can't obtain the headers or the response. And everything is set to null or empty.
https://developer.mozilla.org/en-US/docs/Web/API/Response/type
Or maybe in the server you should add:
Access-Control-Allow-Origin: *
Very late answer but in case someone wants to check whether an error occurred while sending an XMLHttpRequest and then take appropriate actions (on the CLIENT side), then this is a quick workaround:
try{
request.send();
}catch(err){
if(e.toString().startsWith("NetworkError")){
//pasre the string to check error code
//and take appropriate actions
}
}
This is needed because the onreadystatechange function doesn't get executed when a NetworkError occurs and, in fact, the whole script is terminated.