i just found xhr onerror always reject error with same message, it's very hard to find error cause.
xhr.onerror = function() {
reject(new TypeError('Network request failed'))
}

VS

I'd also like to see more meaningful error messages but are the details of the error actually available for retrieval anywhere? e.g. in your second part of the 'VS', where does 'The resource could not be loaded because the App Transport policy requires use of a secure connection' come from, @lloydsheng ? Our clients are sometimes reporting ERR_CONNECTION_RESET and ERR_CONNECTION_CLOSED when trying to log into our web-based application, it would certainly be handy to have more error data to work with...
@bergr01 The second error message was from iOS network framework. because the latest react native direct reference the fetch package. and i found this message available retrieval from
xhr.responseText
Thanks for clarification @lloydsheng - sounds like 'responseText' is intended for relaying the response from the server... I guess in my case (with ERR_CONNECTION_RESET/ERR_CONNECTION_CLOSED) I'm not sure if server actually had a chance to respond (e.g. if problem occurs during SSL handshake) - don't suppose anyone has any experience in programmatically getting a detailed reason for those sorts of connection errors?
@bergr01 In general, the 'responseText' is response from server. but in react native , if the error occur, the error detailed can get from 'responseText'. i think we can make meaningful error messages with it.
At least in NativeScript on Android, I don't see xhr.responseText set in the debugger when this error occurs. However, an Error object is passed to the onerror handler which itself contains a more detailed message.
ref NativeScript/NativeScript#2952
I have done some exploration of this. The conclusion I came to is there is no consistent way to provide more information. On some platforms, more information is available so an implementation that provides more information would just to code for various cases. Granted my exploration was against browsers that have a native fetch implementation so there would exist a _very slight_ chance that the places that need polyfill do all behave in the same manner.
To summarize:
Firefox (49.0): The passed parameter is an Exception. The relevant information is on the name member.
Chromimum (53.0.2785.143): The passed parameter is a ProgressEvent. The closest thing to relevant information says "error." The XMLHttpRequest is accessible via the ProgressEvent but responseText is an empty string. The developer console does contain an error containing relevant information, but that is outside of the executing JavaScript.
NativeScript (2.3.0): The passed parameter is some kind of Error. The relevant information is on the message member.
React Native (inferred from @lloydsheng's comments): Unknown if a parameter is passed but you can access the XMLHttpRequest via closure. Relevant information is on the responseText member.
According to the documentation for Internet Explorer 8, there are no parameter passed to the event handler, which near as I can tell matches the spec. However, implementation may differ from documentation.
Thanks for the investigative work, @vossad01! Because this is obviously complex and inconsistent, I don't think there's much we can do to provide a more useful text via error message.
@mislav - can we try and do it defensively? Also, the error message for onerror and ontimeout are exactly the same.
Not a fix, but the error can be seen in Chrome dev tools > Network tab + hover over "(failed)" cell of the XHR request
I still don't quite understand the reasons for not providing better error handling, but how about the change I show below at least? I just lost several hours trying to call a server only to find out XMLHttpRequest was burying an invalid certificate error. By the time the error got to my onerror() handler, the error object was undefined. Although I'm guessing that my attempt of adding an error object to the onerror() function was futile.
In the meantime, I altered the code in XMLHttpRequest.js to at least dump an error message to the console. That would have saved a lot of head scratching:
/**
* Called when an error is encountered to deal with it.
*/
this.handleError = function(error) {
this.status = 0;
this.statusText = error;
this.responseText = error.stack;
errorFlag = true;
setState(this.DONE);
// ROS: Prevent error from being swallowed invisibly on route to the onerror handler.
console.error(`ERROR: XMLHttpRequest - ${error}.`);
this.dispatchEvent('error');
};
I'm fine for now with this change, but obviously the next time I update the NPM package, I'll have to remember to reapply this change.
@roschler You can use patch-package to automatically apply that patch
Most helpful comment
I have done some exploration of this. The conclusion I came to is there is no consistent way to provide more information. On some platforms, more information is available so an implementation that provides more information would just to code for various cases. Granted my exploration was against browsers that have a native fetch implementation so there would exist a _very slight_ chance that the places that need polyfill do all behave in the same manner.
To summarize:
Firefox (49.0): The passed parameter is an
Exception. The relevant information is on thenamemember.Chromimum (53.0.2785.143): The passed parameter is a
ProgressEvent. The closest thing to relevant information says "error." TheXMLHttpRequestis accessible via theProgressEventbutresponseTextis an empty string. The developer console does contain an error containing relevant information, but that is outside of the executing JavaScript.NativeScript (2.3.0): The passed parameter is some kind of Error. The relevant information is on the
messagemember.React Native (inferred from @lloydsheng's comments): Unknown if a parameter is passed but you can access the
XMLHttpRequestvia closure. Relevant information is on theresponseTextmember.According to the documentation for Internet Explorer 8, there are no parameter passed to the event handler, which near as I can tell matches the spec. However, implementation may differ from documentation.