I have a node server that basically reads a component from a specific path, executes the code, and returns the data to the other server.
Sometimes during the code execution of the component, I get a 403 response.
Error:
ApolloError: Response not successful: Received status code 403
I'm using .catch() to catch the 403 response but it's not helping and there are frequent pod crashes due to the 403.
I have checked this StackOverflow answer - Fetch: reject promise and catch the error if status is not OK?
It mentions that
Since 4xx and 5xx responses aren't network errors, there's nothing to catch
Is this correct?
If the above statement is true, can it be handled like the below:
app.use((req,res) => {
res.status(403).send('');
})
Is 4xx and 5xx network errors?
No, they're HTTP error responses, successfully transferred from the server to the client via the network.
I'm using .catch() to catch the 403 response
I assume you mean with fetch given the question you linked to. This is a common issue (a footgun in my view) with using the fetch API. fetch only rejects its promise on network errors, not HTTP errors. So, it will reject its promise if it can't contact the server. It won't if it successfully contacts the server and receives an HTTP error response.
The answers to the question you link (such as this one) and my linked blog post above describe how to handle this using a common path for network and HTTP errors: When you first get the Response object, check its ok property and throw if it's not true, then handle rejection in a common rejection handler.
But reiterating in case those resources disappear (unlikely, but answers are supposed to be self-contained), using JSON as an example, I'll usually have something like this in my codebase on a project:
async function fetchJSON(...args) {
const response = await fetch(...args);
if (!response.ok) {
// Network was fine, but there was an HTTP error
throw new Error(`HTTP error ${response.status}`);
}
return await response.json();
}
I do that because the vast, vast, vast majority of the time, the code doing the fetch doesn't care whether there was a network error or an HTTP error, it just cares that the fetch (and associated JSON parsing) did or didn't work.
Related
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.
I am using fetch() to get results from an API. As I understand it, there's 2 different types of errors:
an error that my API returns specifically: for example "invalid authentication token"
more generic HTTP errors: for example - network timeout or connectivity was interrupted.
Is there a way to determine the nature of the issue, in such a way that I can retry an API command when it makes sense (like poor network connectivity), but not retry it if it's just going to give the same result as the previous time (like an invalid token error)
Is there a way to determine the nature of the issue, in such a way that I can retry an API command when it makes sense (like poor network connectivity), but not retry it if it's just going to give the same result as the previous time (like an invalid token error)
fetch() only throws if there was some error with recieving the data. If your server responded with an error status, you'd have to check that in the then() block.
#Thomas Thanks! So in general if i enter my catch() block of the fetch(), I can treat that as a network issue?
Think the other way around. If you land in the then() part, your server has responded successfully; wether you like that response (200) or not (404).
If you land in the catch() part of the fetch(), something went wrong with the request and a network error is one of the more likely reasons. An invalid url, like "//", would be another reason to throw.
I got the response from server like this:
Request URL:http://api.bfexchange.net/wallet/balance
Request Method:GET
Status Code:504 Gateway Time-out
Remote Address:52.78.140.154:80
Referrer Policy:no-referrer-when-downgrade
But printing err in catch of fetch API just returns Error object.
fetch(...)
.then(...)
.catch((err) => {
console.dir(err);
});
It prints this(from Google Chrome):
TypeError: Failed to fetch
message: "Failed to fetch"
stack: "TypeError: Failed to fetch"
__proto__: Error
index.js:82
I want to get status code to proper error handling, like server is not responding like something.
Is there a way to get response data in this case? Else, what alternatives can I attempt?
Any advice will very appreciate it!
If the server uses CORS you will get the 5xx response, but it won't be as a rejection; the promise will be resolved with the response. If the server does not use CORS, you won't ever see a response and the promise will always be rejected (unless you use "no-cors", in which case you can get an opaque response that is useful in some service worker scenarios).
When we make any AJAX request, what are the different possibilities for the response failing and how do we verify it on client-side?
Is it purely based on "response.status"
I am using DOJO and see one place where I am getting response from the server, but response.status is "undefined" (dojo.xhrPost response)
More importantly technically speaking from the backend/server-side, do we have to explicitly do/pass something to indicate response failure on the client-side OR is that automatically handled (assume Java in the backend)?
The whole HTTP state is based on the status of the HTTP call. The server side component should be able to send the right failure response code/HTTP Status 4xx/5xx as expected. This is irrespective of the type of server/client side component.
However, not all the failure cases needs to throw 5xx or 4xx status. For example, you may try to add a new record, if record already exists, the server can still send 200 OK response and give message stating - Record already available.
It's all with the webdeveloper's discretion :)
Have you checked the network tab of your developer tools to find the request matching the XHR that failed? It could probably tell you more.
If the status is undefined, I would guess that perhaps the XHR was aborted entirely or that there was an error even connecting, or resolving DNS, etc.
I've carefully read all HTTP error/status codes, still not clear which is the appropriate to return in the following scenario:
The request is an Ajax request, so the handling of the error situation depends on the client javascript code, preferably it will give a notification.
At server side an unexpected error occurs (say DB operation fails), however the exception is handled server side, and appropriate error message (as string) is created there.
The 'unexpected error' implies HTTP 500, however I would like to differentiate between real server internal (and unhandled) errors and handled use cases what I've described above.
Which Http error/status code is the appropriate?
Does it matter if the request a query (using GET) or some update (using POST)?
Both scenarios that you described are server errors. Regardless if it was a DB operation that fails or you server-side code didn't handle an error (unhandled error). Therefore, for the Front-end point of view, A server error has occurred (500 error status).
Now, differentiating an custom application error from an unhandled error, comes down to which server-side technology you are using. You can decorate (add a property) your error object with some information that only your handled application errors would have. Therefore, on the Front-end, if that property is present, it's a known server error.
//500 error - unknown model
{ status: 500, exception: "my unknown error." }
//500 error - known model
{ status: 500, exception: "DB script has failed.", errorCode: 001 }
It shouldn't matter if the call is a GET or a POST. Both Methods could return the same http status code.
The appropriate response is 5xx Server Error. Depending on the type of error you may choose to use "503 Service Unavailable" or "501 Not Implemented", but in the more generic cases opt for "500 Internal Server Error" (GET or POST doesn't matter).
You may choose to provide a custom response body to differentiate between handled error messages and unhandled ones.
There is a list of available status codes. Usually if the request was valid, you'll receive the status code 200. If a resource could not be found, you'll get 404. All the server side errors will result in a 500. If you intend to differentiate between your server side errors, you'll have to catch them manually and return a response with a different status code. Note: Status code 500 is the worst of them all. You should not use it, for example, to return the error messages in case a validation has failed. Use a different status code in this case.