The title is horrible, i know; I'm terrible at titles on SO here.
I'm wondering what would be the best way to present unified error responses in a webapi when errors could be raised deep inside the application.
The errors deep down in the app don't know anything about the web layer (nor should they), so how can the web layer classify myapp.PermissionError
into a 403, json.DecodeError
into a 400, myapp.driver.InvalidValue
into 500, etc.
I have a few ideas, but I'm not a big fan of any of them.
(As the snippets might imply, this is a python app on linux)
Use a lot of
except
blocks to match the exception type i want. This is what i'm currently doing but its growing unwieldy (i'm already up to 8, and there are plenty more to go).try business.DoIt() except DecodingError: respond(400) except PermissionError: response(403) ...etc...
Creating a mapping or list of exception types and map them to response codes. This doesn't seem much better than (1) in the end, but it does clean up the code.
error_map = [(DecodingError, 400), (PermissionError, 403)] try: DoIt() except Exception, exc: for type, code in error_map: if isinstance(exc, type): response(code) return
Add an interface to every exception class that provides the response code, but I don't like this because then the exceptions are carrying web-layer specific information (even if they live deep down in a driver that doesn't care about the web layer at all). I do like how "automatic" the web error response is, though.
class PermissionError(Exception): web_status_code = 403 try: Doit() except: response(exc.web_status_code)