TurboGears / TurboGears/backlash

Add ASGI support for TraceErrorsMiddleware (crash reporting)

Open
#25 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Python
Stars
13
Forks
13
PR merge metrics
No merged PRs in 30d

Description

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 #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 #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 #23 — parent effort; this middleware depends on conventions introduced there.

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with backlash/tracing/errors/middleware.py for the WSGI behavior and backlash/asgi.py for scope filtering and response-started handling. Then inspect backlash/tracing/reporters/mail.py and sentry.py, and use in-process ASGI tests to verify exception reporting, recorded exceptions, non-http pass-through, and the plain 500 or post-start re-raise behavior.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
backend
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
65/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.