Skip to content

Wire Bugsnag into the API server#231

Open
morgan-wowk wants to merge 1 commit intobugsnag/instrumentation-modulefrom
bugsnag/api-server-integration
Open

Wire Bugsnag into the API server#231
morgan-wowk wants to merge 1 commit intobugsnag/instrumentation-modulefrom
bugsnag/api-server-integration

Conversation

@morgan-wowk
Copy link
Copy Markdown
Collaborator

@morgan-wowk morgan-wowk commented May 8, 2026

TL;DR

Integrates Bugsnag error monitoring into the API server.

What changed?

  • Bugsnag is initialized during app startup with the service name tangle-api.
  • The BugsnagMiddleware is conditionally added to the FastAPI middleware stack when Bugsnag is enabled.
  • Unhandled exceptions caught by the global exception handler are now reported to Bugsnag via bugsnag_instrumentation.notify.

How to test?

  • Enable Bugsnag by configuring the appropriate environment variables/credentials.
  • Trigger an unhandled exception in the API and verify it appears in the Bugsnag dashboard.
  • Confirm the middleware is only added when IS_BUGSNAG_ENABLED is True, and that the app starts normally when Bugsnag is disabled.

Why make this change?

To improve observability and error tracking in production by capturing and reporting unhandled exceptions to Bugsnag, enabling faster diagnosis and resolution of issues.

Bugsnag ASGI Middleware

BugsnagMiddleware (source) wraps the ASGI layer and automatically enriches every error event with request context:

  • Client IP from the ASGI scope
  • HTTP method, version, and path
  • Full request URL (scheme + host + port + path + query string)
  • All request headers — with authorization, cookie, x-api-key, and proxy-authorization redacted via params_filters
  • ASGI scope dict as an "environment" tab — opt-in via send_environment=True, off by default

The middleware and the explicit bugsnag.notify() call in handle_error are complementary, not duplicative: FastAPI's exception handler consumes exceptions before they reach the ASGI layer, so handle_error covers normal request errors while BugsnagMiddleware acts as a safety net for exceptions that escape FastAPI entirely (e.g. startup failures, middleware crashes).

Additionally, every Bugsnag event — whether from the middleware or from a direct notify() call — is enriched with a "tangle_context" tab via our before_notify callback, containing: request_id, user_id, pipeline_run_id, and execution_id from the current request context.

Copy link
Copy Markdown
Collaborator Author

morgan-wowk commented May 8, 2026

Warning

This pull request is not mergeable via GitHub because a downstack PR is open. Once all requirements are satisfied, merge this PR as a stack on Graphite.
Learn more

This stack of pull requests is managed by Graphite. Learn more about stacking.

Comment thread api_server_main.py Outdated
@app.exception_handler(Exception)
def handle_error(request: fastapi.Request, exc: BaseException):
exception_str = traceback.format_exception(type(exc), exc, exc.__traceback__)
bugsnag_instrumentation.notify(exc)
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for the noise, I realize you mention this is not ready for review yet, but wanted to add this comment before I forget.

I really like how you added in the orchestrator stack for adding the execution.id to the exception for better tracebility. Not sure if there is anything like that now in the API level? I believe we are adding system level annotations to the source (UI, CLI/tangle-deploy), that "might" be nice to add to this to label the exception better.

Just a thought, if we don't have the plumbing now to easily do this, then not a concern.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is welcome. Good question / topic to look into!

@morgan-wowk morgan-wowk force-pushed the bugsnag/api-server-integration branch from f967108 to bba37bb Compare May 8, 2026 21:05
@morgan-wowk morgan-wowk force-pushed the bugsnag/instrumentation-module branch from cf06f0c to 248ce56 Compare May 8, 2026 21:05
@morgan-wowk morgan-wowk force-pushed the bugsnag/api-server-integration branch from bba37bb to d1e5bdb Compare May 8, 2026 22:38
@morgan-wowk morgan-wowk force-pushed the bugsnag/instrumentation-module branch 2 times, most recently from 66f4c0d to c0d147f Compare May 8, 2026 23:13
@morgan-wowk morgan-wowk force-pushed the bugsnag/api-server-integration branch from d1e5bdb to 368e08e Compare May 8, 2026 23:13
@morgan-wowk morgan-wowk force-pushed the bugsnag/instrumentation-module branch from c0d147f to 4a6f0bc Compare May 8, 2026 23:18
@morgan-wowk morgan-wowk force-pushed the bugsnag/api-server-integration branch 2 times, most recently from ff5439f to 765252d Compare May 8, 2026 23:25
@morgan-wowk morgan-wowk force-pushed the bugsnag/instrumentation-module branch from 4a6f0bc to 7a7696e Compare May 8, 2026 23:25
@morgan-wowk morgan-wowk force-pushed the bugsnag/api-server-integration branch 2 times, most recently from e7d28aa to 666bc18 Compare May 8, 2026 23:32
@morgan-wowk morgan-wowk force-pushed the bugsnag/instrumentation-module branch from 7a7696e to 6842b69 Compare May 8, 2026 23:32
@morgan-wowk morgan-wowk force-pushed the bugsnag/api-server-integration branch from 666bc18 to a5bc1e7 Compare May 8, 2026 23:38
@morgan-wowk morgan-wowk force-pushed the bugsnag/instrumentation-module branch from 6842b69 to 936d216 Compare May 8, 2026 23:38
@morgan-wowk morgan-wowk force-pushed the bugsnag/api-server-integration branch from a5bc1e7 to cd51f98 Compare May 8, 2026 23:40
@morgan-wowk morgan-wowk force-pushed the bugsnag/instrumentation-module branch from 936d216 to 514d0f0 Compare May 8, 2026 23:40
@morgan-wowk morgan-wowk force-pushed the bugsnag/api-server-integration branch from cd51f98 to d7ace7d Compare May 8, 2026 23:41
@morgan-wowk morgan-wowk force-pushed the bugsnag/instrumentation-module branch from 514d0f0 to 365eab5 Compare May 8, 2026 23:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants