Skip to content

Sentry removes chained exceptions during ASGI application crash #5624

Description

@roy-work

How do you use Sentry?

Sentry Saas (sentry.io)

Version

2.35.0

Steps to Reproduce

We have an ASGI application; we use Sentry in it, by way of calling sentry_sdk.init.

We recently had a incident; during that incident, the ASGI application was crashing. Our logs contained:

2026-03-03 16:59:59,994 - uvicorn.error - ERROR - Exception in ASGI application
Traceback (most recent call last):
  File "/…/.venv/lib/python3.10/site-packages/uvicorn/protocols/http/h11_impl.py", line 366, in run_asgi
    result = await app(self.scope, self.receive, self.send)
[snipped]
  File "/…/.venv/lib/python3.10/site-packages/sentry_sdk/integrations/starlette.py", line 408, in _sentry_patched_asgi_app
    return await middleware(scope, receive, send)
  File "/…/.venv/lib/python3.10/site-packages/sentry_sdk/integrations/asgi.py", line 179, in _run_asgi3
    return await self._run_app(scope, receive, send, asgi_version=3)
  File "/…/.venv/lib/python3.10/site-packages/sentry_sdk/integrations/asgi.py", line 268, in _run_app
    raise exc from None
  File "/…/.venv/lib/python3.10/site-packages/sentry_sdk/integrations/asgi.py", line 263, in _run_app
    return await self.app(
  File "/…/.venv/lib/python3.10/site-packages/starlette/applications.py", line 113, in __call__
    await self.middleware_stack(scope, receive, send)
  File "/…/.venv/lib/python3.10/site-packages/sentry_sdk/integrations/starlette.py", line 150, in _create_span_call
    return await old_call(app, scope, receive, send, **kwargs)
[snip more frames]
  File "/…/app/middleware/authorization_middleware.py", line 79, in __call__
    verifier.verify(token, request)
  File "/…/app/token_verifier.py", line 72, in verify
    raise HTTPException(
starlette.exceptions.HTTPException: 401: Failed to Authorize"

Now, that exception is a bug; I think we're supposed to return a 401 response, not raise.

But what hampered us during this incident is that line 72 there is:

        except Exception as e:
            raise HTTPException(
                status_code=status.HTTP_401_UNAUTHORIZED,
                detail="Failed to Authorize",
                headers={"WWW-Authenticate": "Bearer"},
            ) from e

(Note that this is still our code.) Note the from e: there should be an additional exception's worth of stack frames, but the stack trace above terminated there. That is, from e should normally look something like this:

Traceback (most recent call last):
[snip]
RuntimeError: I couldn't do it.

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
[snip]
    raise RuntimeError("ouch") from e
RuntimeError: ouch

Having the first bit (this exception led to the second exception) would have really helped us in the incident.

By default, FastAPI / Uvicorn will emit that "The above exception was …" bit automatically. In fact, I copy/pasted that snippet from a test FastAPI app. So, in a small test, it works; in our production code, not so much.

This frame in Sentry's code, I think, is why we do not, in prod, get chained exceptions in the backtrace:

  File "/…/.venv/lib/python3.10/site-packages/sentry_sdk/integrations/asgi.py", line 268, in _run_app
    raise exc from None

That code is here.

That from None removes the context/exception cause from the exception. There does not seem to be a reason for that in the linked code; this means we lose the context from the exception in our logs.

There is also this line, and I think both from Nones are incorrect.

Sentry should re-propagate the current exception with whatever __context__/__cause__ is has. A simple raise (without "exc") is sufficient.

See Exception Chaining in the Python docs for more information.

Expected Result

Sentry does not de-chain exceptions during an ASGI crash

Actual Result

Sentry de-chains the exception, resulting in our logging library not logging a full stack trace.

Activity

  1. linear-code commented on Mar 10, 2026

    @linear-code
  2. moved this to Waiting for: Product Owner in GitHub Issues with 👀 3on Mar 10, 2026
  3. sentrivana commented on Mar 10, 2026

    @sentrivana
    Contributor

    Hey @roy-work, thanks for taking the time to write a great bug report, it's appreciated.

    I'm unsure why we chose to raise from None in the ASGI integration (or anywhere in the SDK, for that matter), but since we've had support for reporting exception groups/chained exceptions for a while now, I believe it might just be an artifact of the past. We'll investigate.

  4. moved this from Waiting for: Product Owner to No status in GitHub Issues with 👀 3on Mar 10, 2026
  5. added a commit that references this issue on Mar 10, 2026
    dd3de36
  6. alexander-alderman-webb commented on Mar 19, 2026

    @alexander-alderman-webb
    Contributor

    Thanks @roy-work for the accurate investigation and good report!

    Removing from None on master would result in many new issues in Sentry for users who upgrade to a new minor SDK version.
    For this reason we will make the change with the next major. See the PR: #5709

  7. roy-work commented on Mar 19, 2026

    @roy-work
    Author

    would result in many new issues in Sentry for users

    To be perfectly honest, that seems a bit like a spacebar heater. Can I ask why you think users are dependent on broken stacktraces?

    … regardless, … maybe my org can work with that. It looks like a few alpha versions of 3.0 were released to PyPI, but there hasn't been one since October. I'm curious when there might be another? (I'm wondering if maybe we can tolerate a 3.0a version, until such a time as 3.0 is released for real.)

  8. moved this to Waiting for: Product Owner in GitHub Issues with 👀 3on Mar 19, 2026
  9. sentrivana commented on Mar 20, 2026

    @sentrivana
    Contributor

    To be perfectly honest, that seems a bit like a spacebar heater. Can I ask why you think users are dependent on broken stacktraces?

    We consider changes in the SDK that affect issue grouping in Sentry breaking since folks might have different workflows, alerts, dashboards set up with the assumption that errors are reported a certain way. The stability is important in order for us to provide a consistent experience. So while I get your point, the potential for breaking users is high, especially since we're talking about a fundamental integration like ASGI.

    … regardless, … maybe my org can work with that. It looks like a few alpha versions of 3.0 were released to PyPI, but there hasn't been one since October. I'm curious when there might be another? (I'm wondering if maybe we can tolerate a 3.0a version, until such a time as 3.0 is released for real.)

    The next major will realistically take a couple more months. The existing alpha releases are from a previous 3.0 branch that we've since abandoned.

    I guess we could release a small alpha from the new 3.0 branch with the from None fix, but tbh I don't think that's a good idea as you'd be left behind main -- the 3.0 branch is not being worked on actively at the moment, so there won't be regular releases from it to keep it in sync with fixes and features from main.

    Let me think about this a bit more and come back to you.

  10. moved this from Waiting for: Product Owner to No status in GitHub Issues with 👀 3on Mar 20, 2026
  11. sentrivana commented on Mar 20, 2026

    @sentrivana
    Contributor

    We'll add an experimental option in the next release (out in the next two weeks) that you can use to disable the behavior and just use a bare raise:

    sentry_sdk.init(
        _experiments={"suppress_asgi_chained_exceptions": False},
    )

    The plan is to still make this the default in the next major, but this way you can enable it early. We'd be happy to know how it's working for your org once you've enabled it if you feel like sharing.

  12. roy-work commented on Mar 23, 2026

    @roy-work
    Author

    We consider changes in the SDK that affect issue grouping in Sentry breaking since folks might have different workflows, alerts, dashboards set up with the assumption that errors are reported a certain way.

    Hmm. I was not thinking that this change should affect issue grouping; I was thinking this is after Sentry already had whatever data that it was going to capture & upload. (I.e., that we're merely changing the exception's backtrace to the frames up the ASGI middleware stack.)

    We'll add an experimental option in the next release (out in the next two weeks)

    Thank you, that can work, I think.

  13. sentrivana commented on Mar 24, 2026

    @sentrivana
    Contributor

    Hmm. I was not thinking that this change should affect issue grouping; I was thinking this is after Sentry already had whatever data that it was going to capture & upload. (I.e., that we're merely changing the exception's backtrace to the frames up the ASGI middleware stack.)

    We tested the change and it did result in the error being sorted into its own new group. I'm not 100% up to date with the categorization logic on the server but I do believe it takes the stacktrace into account.

    In any case, new release with the experimental option is coming later today.

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

Metadata

Metadata

Assignees

No one assigned

    Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions