what is the xhr error event object details in this scenario? - javascript

I'm testing a simple mobile upload solution - this question is not about the actual upload - in chrome it uploads the pic in firefox the error event fires - so far so good - but now I need why it fires. The event is sent over so surely there is some error info in the object - but I check the spec on the progressevent which I kinda figured out it is sending but I still cant get a error code, description or anything to help me debug - any pointers please?
xhr.addEventListener("error", uploadFailed, false);
function uploadFailed(evt) {
alert("There was an error attempting to upload the file.");
alert(evt.error.toString()); // this is where the trouble starts
// the evt.error is undefined?
}
thnx ;-)

XMLHttpRequest objects have the status or the statusText properties that correspond to the HTTP status of the request. That might be a good starting point. Also checking the JS console and the network tab in the debugger might yield some useful information (especially with CORS issues).
Using the status property, your error handler might look somehow like this:
xhr.addEventListener('error', function ()
{
if (xhr.status >= 500)
{
alert("Something went wrong on the server!");
}
else if (xhr.status >= 400)
{
alert("Something went wrong with the request on our side!");
}
else
{
alert("No HTTP error indicated, yet the error event fired?!");
}
});

Related

Node http.ClientRequest does not fire "error" event

I have the following javascript node.js code:
var options = {
host: "x.y.z"
,path: "/api/abc/"
,method: "GET"
};
var req = http.request(options);
req.on('response' , function(data) {
console.log("response: ",data.statusCode);
done();
});
req.on('error' , function() {
console.log("error");
done();
});
req.end();
I can't get the error event when an actual HTTP request error occurs. What am I missing ?
Preliminary findings: It would appear that the failure case "no response from server" (e.g. due to network issue) does not fire any event. So, the workaround is to create a 'timer' and trap this condition by yourself.
Try using an if / else statement instead of two independent functions.
if(response you want && response.statusCode = 200){
//logic
} else {
//console.log("error")
}
You should create your own Timeout function inside the request. In fact, I believe that after a lot of time (maybe a minute?) the request would fail. But, if you require something more earlier, you can check this thread that asks for the same thing:
How to set a timeout on a http.request() in Node?

React/Redux + super agent, first call gets terminated

I am writing a react-redux app where I am making some service calls in my middlewares using superagent. I have found a very strange behavior where the first call to my search api always gets terminated. I have tried waiting 10-30 seconds before making the first call, and logging every step along the process and I cannot seem to pinpoint why this is happening.
My action creator looks like
export function getSearchResults(searchQuery) {
return {
query: searchQuery,
type: actions.GO_TO_SEARCH_RESULTS
}
}
It hits the middleware logic here :
var defaultURL = '/myServer/mySearch';
callPendingAction();
superagent.get(defaultURL)
.query({query: action.query})
.end(requestDone);
//sets state pending so we can use loading spinner
function callPendingAction() {
action.middlewares.searchIRC.readyState = READY_STATES.PENDING;
next(action);
}
//return error or response accordingly
function requestDone(err, response) {
console.log("call error", err);
const search = action.search;
if (err) {
search.readyState = READY_STATES.FAILURE;
if (response) {
search.error = response.err;
} else if (err.message) {
search.error = err.message;
} else {
search.error = err;
}
} else {
search.readyState = READY_STATES.SUCCESS;
search.results = fromJS(response.body);
}
return next(action);
}
The query is correct even when the call is terminated, I get this err message back :
Request has been terminated
Possible causes: the network is offline, Origin is not allowed by Access-Control-Allow-Origin, the page is being unloaded, etc.
at Request.crossDomainError (http://localhost:8000/bundle.js:28339:14)
at XMLHttpRequest.xhr.onreadystatechange (http://localhost:8000/bundle.js:28409:20)
It appears the page refreshes each time too.
I cannot seem to find any clues as to why this happens, it seems not matter what the first call fails, but then it is fine after that first terminated call. Would appreciate any input, thanks!
UPDATE: so it seems this is related to chrome, I am on Version 47.0.2526.80 (64-bit). This app is an iframe within another app and I believe that is causing a problem with chrome because when I try this in firefox there is no issue. What is strange is only the first call gives the CORS issue, then it seems to be corrected after that. If anyone has input or a workaround, I would greatly appreciate it. Thanks for reading.
Had the same problem, just figured it out thanks to the answer provided by #KietIG on the topic ReactJS with React Router - strange routing behaviour on Chrome.
The answer had nothing to do with CORS. The request was cancelled because Chrome had navigated away from the page in the middle of the request. This was happening because event.preventDefault() had not been called in one of the form submit handlers. It seems Chrome handles this differently than other browsers.
See the answer link above for more detail.
In my case this was happening when I tried to set a random HTTP request header (like X-Test) on the client side and either AWS Lambda rejected it during the OPTIONS request or something else did that.
I don't know about the side effects, but you're getting CORS errors. Add the .withCredentials() method to your request.
From the superagent docs:
The .withCredentials() method enables the ability to send cookies from
the origin, however only when "Access-Control-Allow-Origin" is not a
wildcard ("*"), and "Access-Control-Allow-Credentials" is "true".
This should fix it:
superagent.get(defaultURL)
.query({query: action.query})
.withCredentials()
.end(requestDone);
More information on Cross Origin Resource Sharing can be found here.

How to handle ETIMEDOUT error?

How to handle etimedout error on this call ?
var remotePath = "myremoteurltocopy"
var localStream = fs.createWriteStream("myfil");;
var out = request({ uri: remotePath });
out.on('response', function (resp) {
if (resp.statusCode === 200) {
out.pipe(localStream);
localStream.on('close', function () {
copyconcurenceacces--;
console.log('aftercopy');
callback(null, localFile);
});
}
else
callback(new Error("No file found at given url."), null);
})
There are a way to wait for longer? or to request the remote file again?
What exactly can cause this error? Timeout only?
This is caused when your request response is not received in given time(by timeout request module option).
Basically to catch that error first, you need to register a handler on error, so the unhandled error won't be thrown anymore: out.on('error', function (err) { /* handle errors here */ }). Some more explanation here.
In the handler you can check if the error is ETIMEDOUT and apply your own logic: if (err.message.code === 'ETIMEDOUT') { /* apply logic */ }.
If you want to request for the file again, I suggest using node-retry or node-backoff modules. It makes things much simpler.
If you want to wait longer, you can set timeout option of request yourself. You can set it to 0 for no timeout.
We could look at error object for a property code that mentions the possible system error and in cases of ETIMEDOUT where a network call fails, act accordingly.
if (err.code === 'ETIMEDOUT') {
console.log('My dish error: ', util.inspect(err, { showHidden: true, depth: 2 }));
}
In case if you are using node js, then this could be the possible solution
const express = require("express");
const app = express();
const server = app.listen(8080);
server.keepAliveTimeout = 61 * 1000;
https://medium.com/hk01-tech/running-eks-in-production-for-2-years-the-kubernetes-journey-at-hk01-68130e603d76
Try switching internet networks and test again your code. I got this error and the only solution was switching to another internet.
Edit: I now know people besides me that have had this error and the solution was communicating with the ISP and ask them to chek the dns configuration because the http request were failing. So switching networks definitely could help with this.
That is why I will not delete the post. I could save people a few days of headaches (especially noobs like me).
Simply use a different network. Using a different network solved this issue for me within seconds.

Catch CORS error

I'm trying to load a CORS-disabled image, and get the error:
Cross-origin image load denied by Cross-Origin Resource Sharing policy.
I've tried catching the error as follows, but that obviously will not work.
How can I catch CORS errors after setting the .src property of an image?
Use the onError event.
if(image.addEventListener) {
image.addEventListener('error', function (e) {
e.preventDefault(); // Prevent error from getting thrown
// Handle error here
});
} else {
// Old IE uses .attachEvent instead
image.attachEvent('onerror', function (e) {
// Handle error here
return false; // Prevent propagation
});
}
Code should probably be consolidated so you don't have to write your code twice, but hopefully you've got the idea.

Detect fail of chrome.extension.sendRequest

Hey fellow Chrome Devs, how would one go about detecting when a chrome.extension.sendRequest has failed? I tried this, and no dice:
chrome.extension.sendRequest({ /* message stuff here */ }, function(req){
if(req == null || chrome.extension.lastError == null){
alert("No response. :(");
}
});
But what happens is that the callback never even fires, which is what I half expected. Is there any way to detect when a sendRequest fails?
Thanks!
You could surround it with a try{}catch(err){} to catch any errors thrown, but an error is not thrown if there is no response, and there is also no null response.
This would have been done by design, to allow a message receiver to do it's thing. For instance, it might involve a couple of web service requests, or ajax requests that could take a while.
If you know how long it should take to respond, you should implement a timeout (it would have been nice if the sendRequest function included one)
So, you could do something like this:
var noResponse = setTimeout(100, function() {
alert('No response received within 100ms!');
});
chrome.extension.sendRequest({ /* message stuff here */ }, function(req){
clearTimeout(noResponse);
alert('I have a response!');
});
You need to change....
if(req == null || chrome.extension.lastError == null){
alert("No response. :(");
}
...to....
if(req == null){
alert("No response. :( and the error was "+chrome.extension.lastError.message);
}
As the docs say for sendRequest If an error occurs while connecting to the extension, the callback will be called with no arguments and chrome.extension.lastError will be set to the error message.
http://code.google.com/chrome/extensions/extension.html#method-sendRequest
http://code.google.com/chrome/extensions/extension.html#property-lastError

Categories

Resources