dmontagu / fastapi-utils

Reusable utilities for FastAPI

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Error handling that has access to cbv

jstoebel opened this issue · comments

I would like to make a class based view that can define its own error handling. I know that I can define global error handlers using @app.exception_handler(MyException). But I would love to be able to write an error handler that some how has access to the cbv instance so I can access state that was built up while processing the request. I think this would lead to cleaner code than wrapping everything endpoint in a try/except

I'm imagining something like this:

@cbv(router)
Class MyView:
    @router.get('/hello')
    def hello(self):
        return {'msg': 'hello world'}

    def handle_errors(self):
        """errors happening in this class are routed to here"""

If I was using Flask, there would be a way to do this with their class based view system

I might do something like this

from flask.views import View

class BaseRoute(View):
    def __init__(self, *args, **kwargs):
        """
        do setup here
        """

    def dispatch_request(self, *args, **kwargs):
        try:
            # self.work is implemented by the sun class
            return self.work(*args, **kwargs)
        except MyError as e:
            """
            handle my error
            """
        finally:
            """
            clean up
            """

class GetUsers(BaseRoute):
    def work(self, *args, **kwargs):
        """
        do the actual work of the endpoint
        """

But of course since FastAPI aims to be smarter about types, this is less trivial (after a few hours of looking around I didn't see an obvious way).

Any ideas on how to go about something like this? I'm flexible with the approach to solving it, at the end of the day I want access to self when handling errors without having to do a try/except in every endpoint

Update for anyone stumbling upon this. Middleware turned out to solve my particular problem.

from fastapi import FastAPI, Request
app = FastAPI()
@app.middleware("http")
async def my_middleware(request: Request, call_next):
        try:
            response = await call_next(request)
            something_cool_with_response(response)
        except SomeError:
            # handle your errors here
        finally:
           return response