microdot icon indicating copy to clipboard operation
microdot copied to clipboard

Error handler with exception class

Open DiegoPomares opened this issue 3 years ago • 6 comments

Hi there!

I'm using the second form of the error handler decorator to process some custom exceptions.

The error handler only works when the class of exception thrown is exactly the same as the one specified in the decorator, but it doesn't work if it is a subclass. I was expecting that the exceptions that are subclasses of the one specified in the decorator would be handled as well, pretty much as a try/except block would.

I'm trying to do something like this:

class NotFound(Exception): pass
class FileNotFound(NotFound): pass
class UserNotFound(NotFound): pass
class EntryNotFound(NotFound): pass

...
...
...

@app.errorhandler(NotFound)
def not_found(request, exception):
    return {"error": str(exception)}, 404

So that I can keep the Microdot error handling decoupled from the specific error handling down the line. But I get 500 errors if I raise anything other than NotFound

Is this a conscious design choice?

DiegoPomares avatar Oct 15 '22 11:10 DiegoPomares

I don't have a problem with expanding the way this works so that you get the handler for a parent class invoked, provided that the child class doesn't have a handler defined.

The logic that dispatches the error to a handler is here. The if statement would need to be converted to a while loop that traverses the class hierarchy until it finds a handler. Would you like to make a PR for this change?

miguelgrinberg avatar Oct 15 '22 12:10 miguelgrinberg

Sure! I'll give it a try

DiegoPomares avatar Oct 15 '22 12:10 DiegoPomares

PR ready for review #75

Feel free to change the additions to the docs if you find a better wording :smile:

DiegoPomares avatar Oct 15 '22 19:10 DiegoPomares

@DiegoPomares The MicroPython PR build is not passing. There is no inspect on that platform.

miguelgrinberg avatar Oct 15 '22 19:10 miguelgrinberg

My bad I thought isclass was a builtin and didn't noticed it was added by the IDE, plus I didn't scroll down to see there were issues :facepalm: I'll fix it

DiegoPomares avatar Oct 15 '22 19:10 DiegoPomares

Done

DiegoPomares avatar Oct 15 '22 20:10 DiegoPomares

Please let me know if there's anything else that stands out and I'll be happy to take a look :smile:

DiegoPomares avatar Oct 20 '22 17:10 DiegoPomares

The only thing that I wanted to think about is if there was a way to select the most specialized exception class instead of just the first one, but I haven't had time to think about this and see if it is feasible yet.

miguelgrinberg avatar Oct 20 '22 18:10 miguelgrinberg

I wanted it to behave exactly as you describe but I couldn't think of a straightforward way to do so, my first instinct was to use the MRO but it's completely different in MicroPython and I'm not sure if coding a method that would produce the equivalent of __mro__ in CPython is a good idea tbh...

DiegoPomares avatar Oct 20 '22 18:10 DiegoPomares