Skip to content

fix(errors): forward originalError for unhandledrejection via NaisErrorsInstrumentation - #68

Merged
sindrerh2 merged 1 commit into
betafrom
fix/errors-instrumentation-original-error
Sep 11, 2026
Merged

fix(errors): forward originalError for unhandledrejection via NaisErrorsInstrumentation#68
sindrerh2 merged 1 commit into
betafrom
fix/errors-instrumentation-original-error

Conversation

@sindrerh2

Copy link
Copy Markdown

What

Faro's built-in ErrorsInstrumentation forwards the actual Error instance as pushError's originalError option for window.onerror, but not for unhandledrejection (registerOnunhandledrejection only passes { type, stackFrames }). This means:

  • With preserveOriginalError: true, a rejected promise's real Error never reached a custom beforeSend hook.
  • Faro's built-in listener registers before an app's own unhandledrejection listener, so it pushes an originalError-less item first — a subsequent manual captureException(error) call for the same rejection gets silently dropped by Faro's dedupe.

Fix

Add NaisErrorsInstrumentation, a drop-in replacement for Faro's ErrorsInstrumentation:

  • window.onerror behavior is unchanged (already forwarded originalError upstream).
  • unhandledrejection uses the same logic as Faro's registerOnunhandledrejection (including its reason/detail fallback chain), with originalError now included.
  • init() excludes the built-in ErrorsInstrumentation from getWebInstrumentations() and registers this one instead — exactly one listener per event type, no dedupe race.
  • initialize() is idempotent; destroy() only restores a previously-installed window.onerror if nothing else replaced it since.

Adversarially reviewed (GPT-5.6-Sol) and 3 findings were fixed: an incorrect reason-fallback chain, a destroy() that could clobber a handler installed by other code later, and a missing idempotency guard.

Docs

README updated to describe this behavior and recommend removing redundant app-level unhandledrejection + captureException listeners now that originalError is included automatically.

Testing

  • npx vitest run — 242 passed
  • npx tsc --noEmit — clean
  • npx tsc -p tsconfig.build.json — clean

…orsInstrumentation

Faro's built-in ErrorsInstrumentation forwards the real Error as pushError's
`originalError` option for window.onerror, but not for unhandledrejection
(registerOnunhandledrejection only passes { type, stackFrames }). With
preserveOriginalError enabled this meant a rejected promise's actual Error
instance never reached a custom beforeSend hook. Worse: because Faro's
listener registers first, it pushes an originalError-less item before the
app's own unhandledrejection handler runs, so a manual captureException call
for the same rejection got silently swallowed by Faro's dedupe.

Add NaisErrorsInstrumentation, a drop-in replacement for Faro's
ErrorsInstrumentation: window.onerror behavior matches upstream, and
unhandledrejection is the same logic (including its reason/detail fallback
chain, ported from Faro's registerOnunhandledrejection) with originalError
added. init() excludes the built-in ErrorsInstrumentation from
getWebInstrumentations() and registers this one instead, so there is exactly
one listener per event type and no dedupe race.

Idempotent (initialize() twice is a no-op) and destroy() only restores a
previously-installed window.onerror if nothing else has replaced it since.

Also documents this in the README and adds regression tests covering the
originalError forwarding, the null/plain-object reason fallback, and the
lifecycle edge cases (double-initialize, destroy after a later handler took
over window.onerror).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@sindrerh2
sindrerh2 merged commit 19589cf into beta Sep 11, 2026
6 checks passed
@sindrerh2
sindrerh2 deleted the fix/errors-instrumentation-original-error branch September 11, 2026 15:42
sindrerh2 pushed a commit that referenced this pull request Sep 11, 2026
🤖 I have created a release *beep* *boop*
---


##
[0.7.0-beta.2](apm-v0.7.0-beta.1...apm-v0.7.0-beta.2)
(2026-09-11)


### Bug Fixes

* **errors:** forward originalError for unhandledrejection via
NaisErrorsInstrumentation ([#68](#68))
([19589cf](19589cf))

---
This PR was generated with [Release
Please](https://github.com/googleapis/release-please). See
[documentation](https://github.com/googleapis/release-please#release-please).

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
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.

1 participant