18👍
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.
2👍
In my opinion:
- the second method is not acceptable.
- it will not failed since server will still send out a http response.
- Let me tell you what I do in my projects:
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
- Django admin colours
- Django: use render_to_response and set cookie
- Resize image maintaining aspect ratio AND making portrait and landscape images exact same size?
0👍
I can’t answer whether both methods are acceptable but can only tell you what I do. In my view I catch some specific/explicit errors such as:
- Invalid or missing params in post
- High level errors such as username already present in database (in a signup situation for e.g.)
- All other system errors
I think if you categorize your errors as some specific errors that the user must know about and then everything else then your code will have at the most 2 or 3 return with error routes, which IMHO isn’t so bad.
I use JSON to return errors and my structure is usually such:
respons={}
response["error|ok"]
response["msg"]="User not found"
response["type"]=ERROR_TYPE # only applicable for errors
Obviously this is quite basic but hopefully gives you a general idea. I would recommend against letting the user see the system generated internal server error. That is horrible user experience, even for internal apps.
Hope this helps.
- Failed: Database access not allowed, use the "django_db" mark, or the "db" or "transactional_db" fixtures to enable it
- Can you run a raw MySQL query in Django without a model?
- Confused by Django's claim to MVC, what is it exactly?
- Why does JSON returned from the django rest framework have forward slashes in the response?
0👍
I would take neither of your suggested approaches. I would suggest something along the lines of what Sid said. Why would you not want to write error free code?
I would try to address all possible bugs and errors in the code I write at all times. This includes validating user input. With ajax i think it is important to send the messages back to the user. This is easily accomplished with json.
response_dict = {}
try:
# do action that could cause an error
except ExpectedError as e:
response_dict['success'] = False
response_dict['message'] e.msg # or custom message
return HttpResponse(json.dumps(repsonse_dict))
then in your ajax call back make sure the response is valid, if it is not alert the user of what they have done wrong. don’t leave them hanging you are making an app for them!
- Django: lock particular rows in table
- Place to set SQLite PRAGMA option in Django project
- Using a custom form in a modelformset factory?
- Add method imports to shell_plus
0👍
Use option 1 but not entirely the way you describe it, you should return a HttpResponse with status_code 200 indicating in the response content (using JSON or some text) that a validation error occurred, then, when you process the response on the client with JQuery just check for the response content and detect if there were validation errors.
Example of JSON string for the HttpResponse:
{"errors": "true", "messages": ["Error #1", "Error #2", "etc."]}
Option 2 is not a good practice because internal server errors happens when there is an uncaught exception that that was thrown by the server and commonly is unknown to the programmer.
Don’t use HTTP status codes to denote validation errors, that is not their purpose.
- Django QuerySet object has no attribute 'objects
- What became available_attrs on Django 3?
- Django – disable one of system checks
- Why does JSON returned from the django rest framework have forward slashes in the response?
- What does 'name__iexact' mean in django model filters?