[PR #8850] [MERGED] fix(instrumentation): don't mark redirect APIErrors as span errors #25152

Closed
opened 2026-04-15 22:44:32 -05:00 by GiteaMirror · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/better-auth/better-auth/pull/8850
Author: @GoPro16
Created: 3/31/2026
Status: Merged
Merged: 4/1/2026
Merged by: @ping-maxwell

Base: mainHead: fix/otel-redirect-span-status


📝 Commits (3)

  • 3e19062 fix(instrumentation): don't mark redirect APIErrors as span errors
  • a05e7f2 Merge branch 'main' into fix/otel-redirect-span-status
  • 6854d80 Merge branch 'main' into fix/otel-redirect-span-status

📊 Changes

2 files changed (+93 additions, -12 deletions)

View changed files

📝 packages/core/src/instrumentation/instrumentation.test.ts (+53 -0)
📝 packages/core/src/instrumentation/tracer.ts (+40 -12)

📄 Description

Summary

withSpan unconditionally records all thrown exceptions as SpanStatusCode.ERROR. Better-auth uses throw ctx.redirect(url) — an APIError("FOUND") with status 302 — for flow control in OAuth callbacks. These are successful redirects, not errors, but they show up as error spans in OpenTelemetry traces (Dash0, Jaeger, etc.).

Before: Every successful OAuth callback produces an error span on handler /oauth2/callback/:providerId because the redirect throw is recorded as an exception.

After: Redirect APIErrors (3xx status codes) are detected by duck-typing (name === "APIError" + statusCode in 300–399 range) and recorded with SpanStatusCode.OK + the http.response.status_code attribute instead.

Changes

  • packages/core/src/instrumentation/tracer.ts — extract endSpanWithError() helper that checks for redirect errors before marking span status
  • packages/core/src/instrumentation/instrumentation.test.ts — 3 new tests: redirect sync, redirect async, non-redirect APIError still records ERROR

Test plan

  • Existing instrumentation tests pass (10/10)
  • New test: sync redirect APIError → SpanStatusCode.OK + http.response.status_code: 302
  • New test: async redirect APIError → SpanStatusCode.OK + http.response.status_code: 302
  • New test: non-redirect APIError (404) → still SpanStatusCode.ERROR

🤖 Generated with Claude Code


Summary by cubic

Fixes OpenTelemetry spans incorrectly marked as errors when OAuth callbacks throw redirect APIErrors. Redirect throws now end spans as OK and set http.response.status_code to the 3xx value.

  • Bug Fixes

    • In withSpan, detect redirect APIErrors (name === "APIError", statusCode 300–399) and treat them as non-errors.
    • Record http.response.status_code and set span status OK; non-redirect APIErrors still ERROR.
    • Added tests for sync/async redirects and a 404 case.
  • Refactors

    • Added isRedirectError() and extracted endSpanWithError() in packages/core/src/instrumentation/tracer.ts to centralize status handling.

Written for commit 6854d808f7. Summary will update on new commits.


🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/better-auth/better-auth/pull/8850 **Author:** [@GoPro16](https://github.com/GoPro16) **Created:** 3/31/2026 **Status:** ✅ Merged **Merged:** 4/1/2026 **Merged by:** [@ping-maxwell](https://github.com/ping-maxwell) **Base:** `main` ← **Head:** `fix/otel-redirect-span-status` --- ### 📝 Commits (3) - [`3e19062`](https://github.com/better-auth/better-auth/commit/3e19062c34484c872817a3087e4e6ce8892aff3b) fix(instrumentation): don't mark redirect APIErrors as span errors - [`a05e7f2`](https://github.com/better-auth/better-auth/commit/a05e7f27ff5d22246b45305940b137054a9103e8) Merge branch 'main' into fix/otel-redirect-span-status - [`6854d80`](https://github.com/better-auth/better-auth/commit/6854d808f7e300f6773e4a0be929a62c03dec319) Merge branch 'main' into fix/otel-redirect-span-status ### 📊 Changes **2 files changed** (+93 additions, -12 deletions) <details> <summary>View changed files</summary> 📝 `packages/core/src/instrumentation/instrumentation.test.ts` (+53 -0) 📝 `packages/core/src/instrumentation/tracer.ts` (+40 -12) </details> ### 📄 Description ## Summary `withSpan` unconditionally records all thrown exceptions as `SpanStatusCode.ERROR`. Better-auth uses `throw ctx.redirect(url)` — an `APIError("FOUND")` with status 302 — for **flow control** in OAuth callbacks. These are successful redirects, not errors, but they show up as error spans in OpenTelemetry traces (Dash0, Jaeger, etc.). **Before:** Every successful OAuth callback produces an error span on `handler /oauth2/callback/:providerId` because the redirect throw is recorded as an exception. **After:** Redirect `APIError`s (3xx status codes) are detected by duck-typing (`name === "APIError"` + `statusCode` in 300–399 range) and recorded with `SpanStatusCode.OK` + the `http.response.status_code` attribute instead. ## Changes - `packages/core/src/instrumentation/tracer.ts` — extract `endSpanWithError()` helper that checks for redirect errors before marking span status - `packages/core/src/instrumentation/instrumentation.test.ts` — 3 new tests: redirect sync, redirect async, non-redirect APIError still records ERROR ## Test plan - [x] Existing instrumentation tests pass (10/10) - [x] New test: sync redirect APIError → `SpanStatusCode.OK` + `http.response.status_code: 302` - [x] New test: async redirect APIError → `SpanStatusCode.OK` + `http.response.status_code: 302` - [x] New test: non-redirect APIError (404) → still `SpanStatusCode.ERROR` 🤖 Generated with [Claude Code](https://claude.com/claude-code) <!-- This is an auto-generated description by cubic. --> --- ## Summary by cubic Fixes OpenTelemetry spans incorrectly marked as errors when OAuth callbacks throw redirect APIErrors. Redirect throws now end spans as OK and set `http.response.status_code` to the 3xx value. - **Bug Fixes** - In `withSpan`, detect redirect APIErrors (`name === "APIError"`, `statusCode` 300–399) and treat them as non-errors. - Record `http.response.status_code` and set span status OK; non-redirect APIErrors still ERROR. - Added tests for sync/async redirects and a 404 case. - **Refactors** - Added `isRedirectError()` and extracted `endSpanWithError()` in `packages/core/src/instrumentation/tracer.ts` to centralize status handling. <sup>Written for commit 6854d808f7e300f6773e4a0be929a62c03dec319. Summary will update on new commits.</sup> <!-- End of auto-generated description by cubic. --> --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
GiteaMirror added the pull-request label 2026-04-15 22:44:32 -05:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/better-auth#25152