damon
damon

Reputation: 8477

handling server error(500) in (django) web app

I have written a web app that uses ajax and django .It parses a file ,collects some data from the file ,and then presents the user with results of processing the data.

If the file was not in the expected format,the parsing and data processing would fail and the program would tell the user that the file could not be processed.

I tried this way

def process_file(request):
    success = False
    return_dict = {}    
    ...
    if (request.is_ajax()) and(request.method == "POST"):
        filename = request.POST['filename']
        ...
        data = parse_file(filename)
        results = process_data(data)
        success = True
        return_dict = {'result':results}
     serialized = json.dumps(return_dict)
     if success == True:
         return HttpResponse(serialized,mimetype="application/json")
     else:
        return HttpResponseServerError(serialized, mimetype="application/json")

In javascript,I have a function which checks status of ajax query .If status is not 'success' ,it displays an error message.

This works even if there is a 500 error in django view, when I am using the django server.The server console shows 500 error but still goes on without a hitch. I am wondering if this would be the case if it is deployed in production environment.

Is there a better way to handle the runtime errors in django view ? What do you guys suggest?

Upvotes: 0

Views: 831

Answers (1)

Chris Pratt
Chris Pratt

Reputation: 239290

The problem here is that you're not truly responding to errors. As long as the request was sent as a POST via AJAX, success is always True. This tells you nothing about whether the file could be parsed, or heck, even if a file was uploaded at all.

First and foremost, you code will currently always fail (500 error) because there's no request.post; it should be request.POST.

Second, any time you need to pull a value out of request.POST, you should always you dict.get, i.e.:

filename = request.POST.get('filename')

If the field is not found in the POST data, filename will equal None. You should therefore, branch on this, only going on with the rest of the code if filename is not None, e.g.:

if filename is None:
    return HttpResponseBadRequest()
else:
    # the rest of your code

Third, I'm assuming filename is an input with type="file". If that's the case, it won't actually exist in request.POST, anyways. All file uploads go into request.FILES. The same notes above apply:

filename = request.FILES.get('filename')
if filename is None:
    return HttpResponseBadRequest()
else:
    # the rest of your code

Fourth, both parse_file and process_data seem to be proprietary methods you created, so it's not possible to give you much help there. But remember to judiciously use try...except blocks whenever you're doing anything that could fail, such as reading data from a file, or parsing that data in an assumed format that it's not actually in.

Your parse_file and process_data methods should catch all possible exceptions. Then they can either propagate them upward, raise another custom exception in their place, or simply fail silently returning something like None. It's then up to your view here to respond accordingly, catching the exception or branching on whether the returned value is None or not.

Upvotes: 1

Related Questions