Skip to content

Add ASGI support for TraceErrorsMiddleware (crash reporting) #25

Description

@amol-

Goal

Provide an ASGI counterpart to TraceErrorsMiddleware so ASGI applications (Starlette, FastAPI, bare ASGI apps) can get crash reporting through the existing reporters (email, Sentry).

Done criteria:

  • A new AsgiTraceErrorsMiddleware (e.g. in backlash/tracing/errors/) that:
    • Passes through non-http scopes (websocket, lifespan) untouched.
    • Catches unhandled exceptions, builds the context (context injectors receive the ASGI scope), captures the traceback, logs it, and dispatches it to the configured reporters.
    • Sends a plain 500 Internal Server Error response when http.response.start has not been sent; logs and re-raises when the response already started (matching AsgiDebuggedApplication post-start semantics from Add ASGI support for the interactive debugger #23).
    • Supports the recorded-exception protocol: after the app completes, a backlash.exc_info key stashed in the scope by the framework is popped and reported (ASGI analog of the WSGI environ['backlash.exc_info'] handshake used by TurboGears).
  • Reporters are reused unchanged.
  • Error output goes to the backlash logger / sys.stderr (no wsgi.errors equivalent exists in ASGI).
  • Behavior is covered by in-process ASGI tests mirroring the existing WSGI middleware semantics.

Out of scope: TraceSlowRequestsMiddleware. Its thread-ident stack snapshotting (sys._current_frames()) is meaningless under an event loop and needs a redesign around asyncio.Task.get_stack(); that deserves its own issue.

Why

#23 brings the interactive debugger to ASGI, but production crash reporting (email/Sentry) remains WSGI-only, so ASGI users get development-time parity without the production-facing half. The middleware is structurally a stripped-down AsgiDebuggedApplication (run app, capture, report, plain 500), and the reporters already consume only the transport-agnostic Traceback object, so the port is a thin adapter (~60 lines) over existing scaffolding.

One caveat worth addressing during implementation: EmailReporter uses synchronous smtplib, which blocks the event loop while reporting. Consider offloading reporter dispatch (e.g. asyncio.to_thread) or documenting the trade-off; the Sentry reporter queues internally and is unaffected.

References

  • backlash/tracing/errors/middleware.py (TraceErrorsMiddleware) — WSGI logic to mirror, including the backlash.exc_info / backlash.exc_environ recorded-exception handshake.
  • backlash/asgi.py (AsgiDebuggedApplication, from Add ASGI support for the interactive debugger #23) — established ASGI shell patterns: scope filtering, response-started tracking, post-start re-raise, logger/stderr error sink.
  • backlash/tracing/reporters/ (mail.py, sentry.py) — transport-agnostic reporters to reuse.
  • Issue: Add ASGI support for the interactive debugger Add ASGI support for the interactive debugger #23 — parent effort; this middleware depends on conventions introduced there.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions