Dealing with AJAX errors, not logged in, etc - thoughts on this method?
I'm trying to setup a generic AJAX success/error handler with jQuery that I can use on multiple projects. My reasoning for doing this is because of a number of possible "errors" that could happen during an AJAX request. Here are the ones that I've handled so far and there status number:
- 0: Unknown Error
- 1: Successful
- 2: Not logged in
- 3: Timed out
- 4: Not allowed (based on permissions)
- 404 Error
For the first 5 errors, I've had to handle them manually. To do this, the only way I could find was is to run the cl4.process_ajax
method inside the success function of an AJAX call with uses the status key/property in the JSON data to determine what the status is. For the 404 or some other AJAX error (ie, unparsable JSON), I've used the ajaxError()
global event handler in jQuery.
The basic idea is that an error will be displayed at the top of the screen inside #ajax_errors
when there is an error, sliding down to make it look "pretty". Each of the errors can be clicked on to hide them.
Here is an example of how I'd used it. cl4.process_ajax
could also be put in an if clause only allowing the code to happen if it was successful.
$.getJSON('/path/to/page?c_ajax=1', function(return_data) {
cl4.process_ajax(return_data);
if (return_data !== null && typeof return_data == 'object' && typeof return_data.html != 'undefined') {
$('#div').html(return_data.html);
} else {
$('#div').html('');
}
});
The query parameter c_ajax
tells the login and permission checking to return a JSON array instead of redirecting the user to the login or no access page as it would normally.
The messages that are displayed can easily be customized on the server just by including the error_msg key/property. This will make it easy to deal with things like translation and also make the code more flexible. I've included the ability to display a debug message when in debug so during development it's easy to determine what the error was (vs the generic user message).
The array that's JSON encoded should look something like:
array(
status => the status using the constants in AJAX
error_msg => message to be displayed the user at the top of the page
debug_msg => message to be displayed in debug mode
html => the html to display
... any other data for that request
)
The following is the error handling code:
// setup the cl4 object and the debug flag
// these are typically else where and cl4 has other stuff in it
var cl4 = {};
var cl4_in_debug = TRUE; // probably default to false, but for this makes it easier to test
cl4.default_error_msg = 'There was a error loading some of the content on this page.<br>Try reloading the page or contacting an administrator.';
/**
* attach an AJAX error hander to the ajax_error element
*/
$('#ajax_errors').ajaxError(function() {
cl4.add_ajax_error(cl4.default_error_msg);
});
/**
* Call within a ajax success function to deal with the response of an ajax call
*/
cl4.process_ajax = function(return_data) {
if (typeof return_data != 'object' || return_data === null) {
cl4.add_default_ajax_error(return_data);
return false;
}
if (cl4.in_debug && typeof return_data.debug_msg != 'undefined'/* && return_data.debug_msg != ''*/) {
cl4.add_ajax_error(return_data.debug_msg);
}
// check to see if we've received the status, because we need it for the rest
if (typeof return_data.status == 'undefined') {
return;
}
switch (return_data.status) {
// successful
case 1 :
return true;
break;
// not logged in
case 2 :
cl4.add_default_ajax_error(return_data, 'You are no longer logged in. <a href="/login">Click here to login.</a>');
return false;
break;
// timed out
case 3 :
cl4.add_default_ajax_error(return_data, 'Your login has timed out. To continue using your current login, <a href="/login/timedout">click here to enter your password.</a>');
return false;
break;
// not allowed (permissions)
case 4 :
cl4.add_default_ajax_error(return_data, 'You do not have the necessary permissions to access some of the functionality on this page.');
return false;
break;
// unknown error
case 0 :
default :
cl4.add_default_ajax_error(return_data);
return false;
}
};
/**
* ajax error function, will show a red div at the top of the page if there is a problem with any of the ajax on the page
*/
cl4.add_ajax_error = function(error) {
$('#ajax_errors').append('<div>' + error + '</div>');
$('#ajax_errors div').click(function() {
$(this).slideUp(function() {
$(this).remove();
});
}).slideDown();
};
/**
* Adds a default message if there is no error_msg in the return_data object
*/
cl4.add_default_ajax_error = function(return_data, default_msg) {
if (arguments.length == 1) {
default_msg = cl4.default_error_msg;
}
if (return_data !== null && typeof return_data == 'object' && typeof return_data.error_msg != 'undefined' && return_data.error_msg != '') {
cl4.add_ajax_error(return_data.error开发者_运维问答_msg);
} else {
cl4.add_ajax_error(default_msg);
}
};
Any thoughts on this? Is there a better method? I haven't found much out there on dealing with AJAX "errors" other than data that can't be parsed or 404 (or similar) errors. Also, is there any better way of dealing with these types of errors within jQuery. (I tried using the success handlers, but they seem to be all run after the success handler for the current request.)
Sorry about the amount of code...I wish it was shorter, but
BTW, I wanted to set this as community wiki, but I don't have the checkbox for some reason.
It would be much cleaner if your checking function returned a boolean value specifying if the handler should continue executing or not so you could do something like that:
$.getJSON('/path/to/page?c_ajax=1', function(return_data) {
if(!cl4.process_ajax(return_data)) return;
$('#div').html(return_data.html);
});
Of course you could also clear your div in the if block - but I think the example shows pretty well what's my intention (not writing code related to the basic error check in the handler itself if it can be done in the error checker itself).
精彩评论