I'm using ajax to improve user experience in my Django project. My concern here is how to respond error to browser properly. As far as I know, I can either:
For me, the fisrt method seems more orthodox , as in Python the philosophy of "Explicit is better than Implicit" really counts. But since all sorts of exception checking are removed from the second one, it is cleaner, less fragmented and more readable.
I'm using jQuery to handle ajax request/response and both methods seem working. My questions are:
PS. I do do essential data validation. Please do not stray the topic for that. :)
If you return a response with a status code of 4xx or 5xx this is a an error and will trigger jQueries error
handler. While it is certainly possible to simple return status 200 every time and use a "error" field in the JSON response (like suggested by dm03514) this is bad for two reasons:
It violates good HTTP practice. There is a reason why there are plenty of error-codes defined
You can't use the fact that jQuery already has a error-Handler that lets you separate normal behavior from error handling.
Most of the time the error response will be much different from the non-error response So it simply makes no sense to put the handling of this messages in one piece of JS code. So, to sum things up, use a JSON response with status 200 for your normal responses and return a (appropriate!) 4xx/5xx response for errors. These can carry JSON payload, too, so your server side can add additional details about the error.
In my opinion:
when my project starts, I always pre-add a module named errors
in top of folder structure, firstly, I will write a base Exception class which inherits from Exception
, then write out some common Exception classes like ObjectNotFound
, ValidationError
from my experience. When I think there should raise an exception in my code, I will use exceptions from this module, and when I find new kind of exception need to be handled, I will write a new exception in it.
Then it's the work for how to handle them. As you are using Django, it very easy to catch exceptions through a middleware, you can write something like this:
from youproject import errors
# categorize your exceptions
400_ERRORS = (errors.ValidationError, errors.ParametersMissing, )
403_ERRORS = (errors.AuthenticationError, )
404_ERRORS = (errors.ObjectNotFound, errors.ResourceNotExist, )
class ExceptionHandleMiddleware(object):
def process_exception(self, request, e):
# set status_code by category of the exception you caught
if isinstance(e, 400_ERRORS):
status_code = 400
elif isinstance(e, 403_ERRORS):
status_code = 403
elif isinstance(e, 404_ERRORS):
status_code = 404
else:
# if the exception not belone to any one you expected,
# or you just want the response to be 500
status_code = 500
# you can do something like write an error log or send report mail here
logging.error(e)
response_dict = {
'status': 'error',
# the format of error message determined by you base exception class
'msg': str(e)
}
if settings.debug:
# you can even get the traceback infomation when you are in debug mode
response_dict['traceback'] = traceback.format_exc()
# set header and return the response
....
The code above is a summary of how I do exception handle in my projects, in general, it's about accurate exception controling, proper exception categorizing, and of course 'Explicit is better than Implicit' philosophy.
===UPDATE===
When it comes to how to deal with the corresponding responses in ajax, you can use the new feature in jquery1.5 statusCode
:
$.ajax({
statusCode: {
404: function() {
alert('page not found');
}
}
});
from jquery documentation:
A map of numeric HTTP codes and functions to be called when the response has the corresponding code. For example, the following will alert when the response status is a 404
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With