#post
flask-error-handling
- keep request-specific error handling behavior (e.g.
flask.abort
or otherwise responding to a request) as close the request handler as possible and decoupled from any modules that may be called outside of a request contexty - e.g. I put some
flask.abort(404)
calls in adata_manager
file called both during request + during admin tasks like rebuilding the app’s cache storage bucket (whereflask
is not relevant and a request is not in progress)
Create a custom error class:
# all we care about is the name
class UserNotFoundError(ValueError):
pass
# we care about some metadata too
class GroupNotFoundError(ValueError):
"""
Custom exception to be raised when a group label cannot be found in memory or the Google Cloud Storage bucket.
"""
status_code_default = 404
def __init__(self, message, group_label=None, status_code=None) -> None:
super().__init__()
self.group_label = group_label
self.message = message
self.status_code = (
status_code if status_code is not None else self.status_code_default
)
def to_dict(self) -> GroupNotFoundErrorDict:
return {
"group_label": self.group_label,
"message": self.message,
"status_code": self.status_code,
}
Register an error handler:
How do I get this to actually catch the exceptions and call the handler before they become 500
s?
- Don’t wrap handler code with
try/except
- If you do, the error won’t bubble up to the handler
- There’s no need for a blanket
try/except Exception
asflask
will already catch those for you as500
responses - So, if your error handler isn’t being called and you’re still getting
500
, remove anytry/except
wrapping your handler body
@app.errorhandler(GroupNotFoundError)
def handle_group_not_found_error(
error: GroupNotFoundError,
) -> tuple[PercentilesResponse, int]:
e = error.to_dict()
group_label, status_code = e["group_label"], e["status_code"]
message = "Percentiles: group not found in any cache"
slogger.error(message, group_label=group_label)
return create_error_response(
error=EndpointError(
message=message, exception=None, requestId=flask.g.request_id
),
status_code=status_code,
)
Or catch the custom exception and call the error handler explicitly?
Which is better? Is one better in all cases? Catching seems to be working better…
- Ask Denton!
except GroupNotFoundError as e:
return handle_group_not_found_error(e)