Login

How to Handle Ajax Errors

An Ajax request behaves like a JavaScript thread. While the request is going on, execution of the JavaScript code in the flow of the code carries on. How do you solve possible conflicts and the resulting errors?If you have an Ajax function in your web page, and it does not download the text you expected, can you solve the problem by clicking the Reload (Refresh) button on your browser? If yes, under what conditions does this work? If no, why not?

If there were a problem with the server, would it send an error message? If yes, does the error message come in place of the text you were expecting or there is some Ajax object method that handles this? If no, why not? If the server is dead, does the TCP/IP protocols send an error message? If yes, how do you handle it? If no, why not?

I answer all of these questions in this article.

An Ajax Function without Error Checking

This is a procedure for an Ajax request that does not have any error checking code:

//variable to finally hold the Ajax downloaded text.

pageDoc = "";

var xmlHttp;

try

{

// Firefox, Opera 8.0+, Safari

xmlHttp = new XMLHttpRequest();

}

catch (e)

{

// Internet Explorer

try

{

xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");

}

catch (e)

{

try

{

xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");

}

catch (e)

{

alert("Your browser does not support AJAX!");

}

}

}

xmlHttp.onreadystatechange=function()

{

if (xmlHttp.readyState == 4)

{

pageDoc = xmlHttp.responseText;

}

}

xmlHttp.open("GET","http://localhost/cgi-bin/sendPge2Str.pl",true);

xmlHttp.send(null);

The first statement declares the variable that will hold the downloaded text. JavaScript needs an Ajax object to make the Ajax request. The next statement is an “integrated” try-catch block. This statement is long because different browsers and different Internet Explorer versions have different ways of instantiating the Ajax object. Here the name of the Ajax object is xmlHttp.

The statement after that defines a method for the Ajax object. This method is called each time the state of the Ajax object changes. The final change of state occurs when the readyState is 4. When the readyState is 4, the method of the Ajax object defined is executed. At this point the text has been downloaded completely and is ready for use at the browser.

The statement (xmlHttp.open()) that follows opens the connection for the request to be made. The statement after that makes the request. When all of the text has been downloaded, the readyState property becomes 4 and executes the defined object.

Clicking the Reload Button

This is the rule for any web page, including that with an Ajax function like the one above. When a web page is being displayed or after it has been displayed, and you realize that all of the HTML elements (recourses) have not been downloaded, you should click the Reload (Reload) button on the browser. When you do this, then all of the HTML elements (recourses) should be re-downloaded from the server. Solving an error problem like this works when there is an accident (temporary error) in the server or transmission line.

Note: this works as long as the erroneous downloaded Ajax content is not cached by the browser. Many browsers will cache the Ajax downloaded text (content) by default; so, when you click Reload button, the downloaded Ajax text is taken from the browser cache. It is possible for you to make your downloaded Ajax content not be cached. You do this at the script at the server. That is, you do this at the script at the server that sends the Ajax text (content). PHP, the computer script language, has a good way of doing this. However, we shall not discuss that here.

As I said above, clicking the Reload button on the browser to solve a download error Ajax problem should work when the problem was actually an accident from the server or from the line.

{mospagebreak title=Server or Transmission Line is not functioning}

I can only give you my experience here. If the server or the transmission lines stop functioning after the user sees his web page on the screen, no Ajax text or error message will be downloaded. Nothing would come in place of the Ajax text. Now, what I have said here is my experience.

Server script does not function

It is possible for you to write a script that does not function at the server. I am talking here about the script that has to send the Ajax text from the server to the client. If the script is not functioning, and everything else is functioning, you will definitely not have the downloaded Ajax text. However, the server may send an error message in place of the Ajax text. The user would then see the error message instead of the Ajax text. The best way to avoid this is to make sure that your script does not have errors.

The readyState property of the JavaScript Ajax object

The "readyState" property keeps track of the current stage of the request by returning an integer. The readyState property of the JavaScript Ajax object can have the value 1, or 2, or 3, or 4. The meanings of these values are as follows:

0: uninitialized

1: loading

2: loaded

3: interactive

4: complete

The value to always use is the last one, which indicates that the download has been completed. See the illustration in the Ajax code above. The question is, “can any of these values be used to check errors?” The answer is no. You cannot use any of these values to determine whether an error has occurred. You can use these values just to check which stage the response of the request has reached.

{mospagebreak title=HTTP Status}

When you are working with HTTP servers you should expect the HTTP errors or status information given below. These errors/status messages can occur when the transmission line and the server are okay.

200: OK

This means the request has succeeded. The client’s request was successfully received, understood, and accepted.

404: Not Found

This means the server has not found anything matching the Request- URL.

I have just mentioned two messages here; there are many others. This is just a short list:

200: "Ok"

301: "Moved Permanently"

304: "Not Modified" (page hasn’t been modified)

404: "Not Found"

403: "Forbidden"

401: "Unauthorized" (wrong password)

These messages are sent by the server. The Ajax object has two properties to indicate these error/status conditions. The properties are the status and the statusText properties. The status property holds a number. For example, if the request was successful, the status property will hold the number 200; if it did not find the item (i.e. if the request failed), it will hold the number 404.

The statusText properties holds the only the text corresponding to a number. For example, if the request was successful, the statusText property will hold the text “OK”; if it did not find the item (i.e. if the request failed), it will hold the text "Not Found."

You can use either of these two properties to check error or status conditions. Remember that this is applicable when the transmission line and the server are all right. Note: most of the time they are all right; so it is these HTTP status messages that always indicate errors. If your script does not function, it will also indicate that.

The most important HTTP status code is 200: "Ok." This indicates that the request was accepted by the server. The number is indicated by the Ajax object status property, while the text, “OK,” is indicated by the Ajax object statusText property. The following code segment shows how to use the status number 200 for error checking.

xmlHttp.onreadystatechange=function()

{

if (xmlHttp.readyState == 4)

{

if (xmlHttp.status == 200)

{

pageDoc = xmlHttp.responseText;

}

}

else

{

//report error – to the client.

}

}

This code segment is the modified version of the onreadystatechange method of the Ajax object. Before I explain the code, let me first make the distinction between the readyState being equal to 4 and the status being equal to 200. When the readyState property is equal to 4, it means that the transaction is complete; that is, something has been downloaded. However, what has been downloaded may not be the Ajax text you were expecting. It may be an error message from the server (in the form of an HTML document) if your script was not functioning (had bugs); I mentioned this above.

When the status property is equal to 200, it means that the server received your request successfully, understood, and accepted it; it does not mean that the server has sent to the client, what the client requested. On the other hand, when the readyState property is equal to 4 it means that the client has received something, but not necessarily what you requested.

You need both properties to be sure that you have downloaded what you wanted, as I explain below with the code segment above.

Inside the definition of the onreadystatechange method above, you have an if-statement. This statement checks to see if the readyState is 4. If it is, it means that something has been downloaded to the client computer. In order to be sure that what is downloaded is what we wanted, we have to test to see if the status is 200. If it is 200, then we received what we wanted, so we go on to do what we want to do with the downloaded text; if it is not 200, then we issue an error message.

Now, you may make this comment: the status number 200 means that the server received your request successfully, understood, and accepted it; this does not mean that the server sent anything back to the client. How can we be sure that the client (you) received what he wanted? This is a sensible question. However, what you should know is that, almost all the time, when the server receives the request, understands and accepts it, the client receives the correct reply (text). I will not explain the details of that in this article.

So, the above code segment is the minimum you should have in your Ajax procedure.

{mospagebreak title=Thread effect of Ajax Request}

An Ajax request behaves like a JavaScript thread. While the request is going on, execution of the JavaScript code in the flow of the code carries on, below the statement of the Ajax request. You may want the statements below the Ajax request to use the result (downloaded text) of the Ajax request. The problem is, you may never know when the request will be complete (when the text is completely downloaded). By the time the request is complete, the statements below the request statement would have been executed (without the downloaded text).

If it is possible for you to use the Ajax result (downloaded text) in the onreadystatechange method of the Ajax text, to do so. This is the best way to avoid the conflict.

If you really must use the Ajax result in the statements below that of the Ajax request, then you should have a while-loop below the Ajax request that will be looping and checking to see if the text has been downloaded, before execution of the statements below the Ajax request continues. The xmlHttp.onreadystatechange method should have a statement to indicate to the while-loop if the required result has been received.

Response is taking longer than it should

Here I show you haw to handle the situation when the response is taking longer than it should. The thing to do here is to abort the Ajax request when you believe it has taken too long. You will need to determine, however, how long is too long.

The Ajax object has the method called abort(). This function is used to abort the Ajax request. When the request is aborted, the readyState property is reset to zero and nothing is downloaded; you do not need to worry about the readyState or status properties. The following code segment, typed below the Ajax procedure, aborts the Ajax request after five seconds:

function abortAjax()

{

xmlHttp.abort();

}

setTimeout("abortAjax()", 5000);

Conclusion

It is not possible to give a clear-cut answer to any of the questions asked in the introduction of the article. There are conditions under which, if you click the Reload button, you will get what you want. There are also conditions when this will not be helpful. Always have the readyState and status property. This will clarify many problems. Do not forget the thread effect of the Ajax request. I showed you in the last section above how to avoid possible conflict.