- The Book of Dojo
- Quick Installation
- Hello World
- Debugging Tutorial
- Introduction
- Part 1: Life With Dojo
- Part 2: Dijit
- Part 3: JavaScript With Dojo and Dijit
- Part 4: Testing, Tuning and Debugging
- Part 5: DojoX
- The Dojo Book, 0.4
Errors and Timeouts
Submitted by jchimene on Tue, 06/05/2007 - 18:44.
Regular web requests and Ajax requests with dojo.xhrGet/Post are much alike. Both use URL's and both use the HTTP protocol. But with browser requests, it is always clear to user when something goes wrong. You may get a 404 - Page Not Found, or a Server Unavailable, or at least something that says "Error". Ajax requests happen in the background, so when they error out the user won't know. Even worse, if the response never comes the browser may appear to lock up.
That's why it's extremely important to provide an error handler and a timeout handler with any dojo.xhrGet/Post calls. You should consider these as critical as URL or the load function
At the very least, you should alert the user that something went wrong. Here's an example:
dojo.xhrGet({ url: "/cgi-bin/timeout.cgi", load: function(data){ document.myForm.myBox.value = data; dojo.byId("boxLoadTime").innerHTML = new Date(); }, error: function(err){ console.debug("Holy Bomb Box, Batman! An error occurred: ", err); }, timeout: 2000 });
The error() function takes the same arguments that load() does. But unlike load(), the only useful parameter is data, which contains the error message. You can also find out what kind of error was generated by looking at the error object's "dojoType" property. It will usually be "timeout" or "cancel", but other error types are possible.
The timeout, given in milliseconds, defaults to 0, which means "wait forever". Even if you expect the request will take a long time, you should set a high value here (e.g. 15000 = 15 seconds), not 0.
- Printer-friendly version
- Login or register to post comments
- Subscribe post
REST compliance?
Hi,
I'm working on a "login" widget, using the "Representational State Transfer" (REST) architecture. The dijit-like widget POST in background using dojo.xhrPost.
RESTful means, on authentification success, server just perform a "202-Accepted" HTTP header (and nothing else!). Alright, it's treated by the "load" function. Cool!
But server can also perform : on wrong login/password, a "401-Unauthorized" header, or a "400-Bad Request" for invalid login/password.
Both are treated by the "error" function. But do I know which one has been triggered, 400 or 401?
Debugging responseObject.message gives me a "bad http response code:400" or "bad http response code:401". HTTP response code is included, at the end, but no way to access it by a standadized way. Regexpressing sounds crappy to me...
Is there a better way?
Please post support questions in the Support Forums
These book pages arent commentable for support, its for content corrections and updates.
one of them should contain the actual error code at some point in them... otherwise you can run a regexp to strip non numerical data from the string and get the code...
-Karl
I'm working on memory here,
Sorry, if responding here was inappropriate. I saw that you asked to move the question to support. I'll repost there, once I see the question.
I'm working on memory here, so verify my answer.
Your error: function should receive two arguments, response and ioArgs. The ioArgs object will contain an xhr property, which is the xhr (XmlHttpRequest) object used to pass your request to the log-in server. The xhr object will contain a status property, which should just be the status code (400, 401, etc) of the request.
Let's assume you named your error handler "authentication_error". Then the following snippet should help you on your way to a more REST-ful existence (I know, punny).
It's working, thanks!
Sorry if I posted in the wrong section.
ioArgs has the right properties, as you descibe :
ioArgs.xhr.status => 401
ioArgs.xhr.statusText => "Unauthorized"
I thought ioArgs was frozen before the request, but I was wrong...
Now, I can REST in peace!
Refer to the test cases in dojo/tets/_base/xhr.html
There are many possible exceptional flows which are very common when using XHR within a secure web application. For example, consider 403 Not authorized exceptions. We should really beef up this page to document how to deal with these common conditions.
For now, it may be helpful to point out the test cases may be helpful to understand the various call options on ioargs and conventions for handling results.
See dojo/test/_base/xhr.html for some of these use cases
Good information on xhrXXX() api's
The
IO transport information in the porting guide is very good information that should be moved into this section of the book.
error params
Above you say: "The error() function takes the same arguments that load() does. But unlike load(), the only useful parameter is data, which contains the error message."
But the Hello Ajax World! a couple pages ago uses this:
Would be useful if all of the paramaters to error/load were described somewhere in more detail - what does an "error" object look like, etc.
Thanks,
Josh
I agree
I agree with this request, more information is needed in this section - for example, what data type is the error? What properties and functions does it expose? Annoyingly there is no mention of it in the API docs.
To answer your question above the key part of the quoted statement is "useful parameter". Clearly then the implication is ioArgs has no useful information as far as error processing is concerned so it is omitted here in the method signature.
Thx.
Handling HTTP 301/302 redirects
To handle redirect responses like 301/302 you can use xhr.getResponseHeader. Here's an error function to automatically handle simple redirects:
if (ioArgs.xhr && (ioArgs.xhr.status == 301 || ioArgs.xhr.status == 302)) {
var url = ioArgs.xhr.getResponseHeader('Location');
console.info("Received HTTP redirect", ioArgs.xhr.status, url);
// .. app-specific handling, or try automatic forwarding:
// avoid complex redirect chains
var redirectCount = ioArgs.args._redirectCount || 0;
if (redirectCount > /* some sensible number */ 2) return;
// make a clone of original xhrGet/Post
var kw = {
load: ioArgs.args.load,
error: ioArgs.args.error,
timeout: ioArgs.args.timeout,
handleAs: ioArgs.handleAs,
url: url,
_redirectCount: redirectCount + 1
};
try {
dojo.xhrGet(kw);
} catch(e) {
// this definitely happens if redirect url is outside domain
console.error("Error following redirect!", e);
// send along to error handler
kw.error(e, {args:kw});
}
} else { // default error handling
console.error("xhr error", data, ioArgs);
alert('Error: '+data);
}
}
xhrGet: how to check for the readyState of the AJAX request?
Can we check the readyState of AJAX request when we are using dojo.xhrGet?
does load function is called only when readyState is 4?