XMLHttpRequest Send() throws error despite onreadystatechange handler - javascript

I am using XmlhttpRequest to send a POST requests on localhost and chrome developer tools console and network to verify the requests.
I have two methods:
Method1 send the post requests.
Requesthandler handles the requests response.
When the request is successful (200) it does not throw an error and the request handler outputs a message on console. But when the request is unsuccessful. My console throws an error despite the request handler.
For example, If I purposely set the wrong url adress. I expect a 404 status Not Found exception and the request handler to output a message on console. Despite it happening, it still goes ahead and throws on the error on Send() Method.
Why xmlhttprequest.send() throws errors despite handling responses on the onreadystatechange event?
Method1(Sends Requests)
RequestHandler(Handles responses)
Console Message:
Thrown Error:

Related

How can a JS script capture the details of a CORS request failure? [duplicate]

Is it possible to get the error code of a failed preflight request so that I can print a meaningful error message? (Or is there a habit of printing a static error for all failed preflight requests no matter the code?)
Clearly, the status code 401 is printed to the console, but the error handler or a .catch() statement only receive the error object thrown.
If I remove the header that triggers the preflight, I get to handle the response myself and I can extract the status code.
// also note that the returned code 401 in first screenshot is wrong. But that's another question..
No, it isn't.
If the status code of the preflight response is not 200, then the Same Origin Policy will prevent any information about the response from being extracted from it.
I've just finished setting up a web API to always return 200 OK status for OPTIONS requests for this reason.
Unfortunately not. All fetch returns is a TypeError with message "Failed to fetch".
> fetch('https://stackexchange.com/404').then(x => console.info(x), error => console.error(error))
× TypeError: Failed to fetch
I tried to manually send another preflight-request and grab the response code of that.
> fetch('https://stackexchange.com/404', { method: 'OPTIONS' }).then(x => console.info(x), error => console.error(error))
× TypeError: Failed to fetch
But that just triggers another preflight and still doesn't let me at the actual failed request.

Is 4xx and 5xx network errors?

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.

XHR request shows canceled status in Chrome (not CORS)

I make an XHR Post request in Chrome and it immediately returns with an response with a type of error with no detail info. In Chrome the response status shows up as "canceled". However the request actually reaches the server and is processed by the server (verified with a breakpoint). But the XHR error response and Chrome response status of "canceled" occurs before the request reaches the server. I'm testing using a local webserver and app server with a single origin of "local.mydomain.com". So there is no cross-domain implications. What could be causing this behavior?

Why Is My catch Block Not Catching "Cross origin requests are only supported for protocol schemes: http..."

I have a JavaScript script that is using the jquery post command to log into a server and obtain a token. I've wrapped my code in a try block with a catch block that looks like this:
catch (error)
{
alert(error.message);
}
My code runs fine, but to test it thoroughly, I intentionally changed the protocol so that the url looks like this:
"htt://some.domain:8080/jsonrpc"
My code does not catch the error and display the alert. Rather, the Chrome console shows the following error:
XMLHttpRequest cannot load htt://some.domain:8080/jsonrpc. Cross origin requests are only supported for protocol schemes: http, data,
chrome, chrome-extension, https, chrome-extension-resource.
I would expect some kind of malformed url exception instead of the error in the console.
The results of other intentional errors such as incorrect password result in exceptions that are caught.
Thanks
Because Ajax is asynchronous. The error occurs outside the try/catch block.
This class of error can be detected in XMLHttpRequest by the status changing to 0. (This status code also covers a few other error states though, so you can't be precise).
The error handler you can pass to jQuery ajax will fire when the status is 0.

How to handle CORS error code?

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.

Categories