jeffery_the_wind jeffery_the_wind - 3 months ago 18
Python Question

Exception Handling in Django - Is this necessary?

Is this:

@login_required
def remove_photo(request):
if request.is_ajax():
try:
BirdPhoto.objects.get( pk = request.POST.get('image_id') ).delete()
except Exception:
raise Exception
return HttpResponse(json.dumps({'msg':'success'}), content_type='application/json')


better than this:

@login_required
def remove_photo(request):
if request.is_ajax():
BirdPhoto.objects.get( pk = request.POST.get('image_id') ).delete()
return HttpResponse(json.dumps({'msg':'success'}), content_type='application/json')


? I have to admit, I don't pay as much attention to error handling and testing as I should. So I just wrote this new function, and I was thinking I should make sure I am handling the errors. Once I kind of got to the basic level of handling errors, I looked at it and said to myself: this isn't really doing anything. It seems to me the two functions will act the same way. This is django, so in production environment the server should catch this and just return a general http response. Am I OK leaving it as the 4 line version and instead of the 6 line version?

Answer

The first one is actually worse than the second one. If the second variant raises an exception, it will be a specific exception such as BirdPhoto.DoesNotExist, and your logfiles or the debug view will show you what the exact error is. The first variant will catch the more specific exception, and raise a useless Exception with no error message.

The first rule of exception handling is be specific. You should catch specific exceptions that you know might occur, and specifically handle the error case the way you want. In this case, you know that the id can be invalid, and BirdPhoto.objects.get() might raise a BirdPhoto.DoesNotExist exception. You should catch that exception specifically, and handle it appropriately -- for example by returning a response with status code 404:

@login_required
def remove_photo(request):
    if request.is_ajax():
        try:
            BirdPhoto.objects.get(pk=request.POST.get('image_id')).delete()
        except BirdPhoto.DoesNotExist:
            return HttpResponse(json.dumps({'msg': 'error'}), status=404, content_type='application/json')
        return HttpResponse(json.dumps({'msg':'success'}), content_type='application/json')

Now if the code raises an exception that you did not expect, a 500 Internal Server Error will be returned, and the debug view or logfiles will show the exact error message. You can then fix your code, or if the exception is to be expected, handle the exception appropriately.

Comments