Skip to content

Improving error handlers to satisfy both template and API server use cases #640

@TGoddessana

Description

@TGoddessana

So I'm using the flask server for two things.

  1. a template-based server-side rendering server. It returns a web page.
  2. Building an API server using flask-smorest.

Here I ran into a problem with handling errors. If I wanted the server to handle errors like 404 in the template use case, I could register an error handler function to return the appropriate template. like this:

def _register_error_handlers(app):
    for errcode in [401, 403, 404, 500]:
        @app.errorhandler(errcode)
        def render_error(error):
            error_code = getattr(error, "code", 500)
            return render_template(f"error_{error_code}.html"), error_code

But the problem is that this overrides the error handler defined by flask-smorest. If I throw a 404 error in the API use case (flask_smorest.abort()), it will be caught by the error handler I defined "for templates" and will result in an HTML error, as opposed to the intended JSON response.

It wasn't easy to find a way to handle both of these methods.
Here's what I think is the ideal error handling provided by flask-smoret.

from flask import abort as flask_abort # errors in the default flask
from flask_smorest import abort as api_abort # api errors

# pseudocode...
@blp.response(UserSchema)
def users_api():
    # omit
    if not user:
        api_abort(404) # this returns a 404 JSON response (caught by the error handler currently present in flask-smorest)

@blp.response
def users_view():
    # similarly omit
    if not user:
        flask_abort() # this raises an HttpException from werkzeug.

I was thinking that flask-smorest could arbitrarily subclass HTTPException and register it in ErrorHandlerMixin, but I'd like to know what you think about this.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions