Django - exception handling best practice and sending customized error message

前端 未结 2 1736
醉话见心
醉话见心 2020-12-13 04:26

I am starting to think about appropriate exception handling in my Django app, and my goal is to make it as user-friendly, as possible. By user-friendliness, I imply that the

2条回答
  •  有刺的猬
    2020-12-13 05:07

    The status codes are very well defined in the HTTP standard. You can find a very readable list on Wikipedia. Basically the errors in the 4XX range are errors made by the client, i.e. if they request a resource that doesn't exist, etc. The errors in the 5XX range should be returned if an error is encountered server side.

    With regards to point number 3, you should pick a 4XX error for the case where a precondition has not been met, for example 428 Precondition Required, but return a 5XX error when a server raises a syntax error.

    One of the problems with your example is that no response is returned unless the server raises a specific exception, i.e. when the code executes normally and no exception is raised, neither the message nor the status code is explicitly sent to the client. This can be taken care of via a finally block, to make that part of the code as generic as possible.

    As per your example:

    def test_view (request):
       try:
           # Some code .... 
           status = 200
           msg = 'Everything is ok.'
           if my_business_logic_is_violated():
               # Here we're handling client side errors, and hence we return
               # status codes in the 4XX range
               status = 428
               msg = 'You violated bussiness logic because a precondition was not met'.
       except SomeException as e:
           # Here, we assume that exceptions raised are because of server
           # errors and hence we return status codes in the 5XX range
           status = 500
           msg = 'Server error, yo'
       finally:
           # Here we return the response to the client, regardless of whether
           # it was created in the try or the except block
           return JsonResponse({'message': msg}, status=status)
    

    However, as stated in the comments it would make more sense to do both validations the same way, i.e. via exceptions, like so:

    def test_view (request):
       try:
           # Some code .... 
           status = 200
           msg = 'Everything is ok.'
           if my_business_logic_is_violated():
               raise MyPreconditionException()
       except MyPreconditionException as e:
           # Here we're handling client side errors, and hence we return
           # status codes in the 4XX range
           status = 428
           msg = 'Precondition not met.'
       except MyServerException as e:
           # Here, we assume that exceptions raised are because of server
           # errors and hence we return status codes in the 5XX range
           status = 500
           msg = 'Server error, yo.'
       finally:
           # Here we return the response to the client, regardless of whether
           # it was created in the try or the except block
           return JsonResponse({'message': msg}, status=status)
    

提交回复
热议问题