GithubHelp home page GithubHelp logo

Support for CorrelationIdPlugin and CorrelationIdPlugin still executing when application encounters an exception about starlette-context HOT 5 CLOSED

tomwojcik avatar tomwojcik commented on May 18, 2024
Support for CorrelationIdPlugin and CorrelationIdPlugin still executing when application encounters an exception

from starlette-context.

Comments (5)

tomwojcik avatar tomwojcik commented on May 18, 2024 1

I removed my answers twice. At first I thought there's nothing to fix, then I've noticed what the issue was, but now I still think there's nothing to fix.

Originally I was confused because you wrote

I'd expect those headers to be set for all requests.

but I think you meant responses. So let's dig into it.

ExceptionMiddleware is added automatically as the last one, so the first one to be run on response and so response headers will be set after that.

But you ask about 500, which is handled by ServerErrorMiddleware.

ServerErrorMiddleware - Ensures that application exceptions may return a custom 500 page, or display an application traceback in DEBUG mode. This is always the outermost middleware layer.

As it's outermost there's nothing I can do about it.

So if you want to set response headers for 500 or Exception, you need to add another middleware only to handle these two or override build_middleware_stack method from Starlette.

I think the best solution for that problem would be to add another middleware which only does try catch for 500 and Exception.

Anyway, I will write some tests and examples for that over the weekend.

class Starlette:
    def __init__(
        self,
        debug: bool = False,
        #  ... more things ....
        middleware: typing.Sequence[Middleware] = None,
        exception_handlers: typing.Dict[
            typing.Union[int, typing.Type[Exception]], typing.Callable
        ] = None,
    ) -> None:
        self.exception_handlers = (
            {} if exception_handlers is None else dict(exception_handlers)
        )
        self.user_middleware = [] if middleware is None else list(middleware)
        self.middleware_stack = self.build_middleware_stack()

    def build_middleware_stack(self) -> ASGIApp:
        debug = self.debug
        error_handler = None
        exception_handlers = {}

        for key, value in self.exception_handlers.items():
            if key in (500, Exception):
                error_handler = value
            else:
                exception_handlers[key] = value

        middleware = (
            [Middleware(ServerErrorMiddleware, handler=error_handler, debug=debug,)]
            + self.user_middleware
            + [
                Middleware(
                    ExceptionMiddleware, handlers=exception_handlers, debug=debug,
                )
            ]

from starlette-context.

tomwojcik avatar tomwojcik commented on May 18, 2024 1

@derekbekoe this case is now supported. https://github.com/tomwojcik/starlette-context/pull/79/files

from starlette-context.

derekbekoe avatar derekbekoe commented on May 18, 2024

Yes the headers x-request-id and x-correlation-id being set in responses was what I meant. Updated the initial issue comment to fix the typo.

from starlette-context.

tomwojcik avatar tomwojcik commented on May 18, 2024

I was digging into it for some time and I don't think there's a clean solution for that.

I don't think you can do much by adding additional middleware. Subclassing Starlette and creating your own build_middleware_stack is a terrible idea.

For exceptions that are not 500 (basically those that are handled), you need to assign headers in exception function like in here.

async def custom_exception_handler(request: Request, exc: Exception):
return JSONResponse({"exception": "handled"}, headers=context.data)

So you can handle that RuntimeError quite easily but there's no solution for all exceptions.

For 500 or anything that isn't handled by your handler_functions, it's impossible in the current state of Starlette.

Please consider closing this ticket or opening a PR. I will leave this ticket open as I don't know if you have any ideas. I run out of them.

from starlette-context.

derekbekoe avatar derekbekoe commented on May 18, 2024

I will close this issue. Thanks for the explanation.

from starlette-context.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.