Skip to content

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

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.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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