Skip to content

FRD: Error Tracking Wrapper

Document Summary

FieldDetails
Feature NameError Tracking Wrapper
StatusDraft
OwnerDavid Holmes
ContributorsEngineering
Target Releasev2.0.0
Related LinksADR-051 (Provider Pattern), ADR-023 (Wide Events Logging), ADR-027 (Default Tech Stack), ADR-014 (Open Source First)
Last Updated2026-06-02
Open Source Libraries@sentry/browser, @sentry/node, @sentry/react
DocumentationSentry JavaScript Docs · React Guide · Node.js Guide · Error Boundaries

This FRD ships @dmwd-io/error-tracking as an optional package that re-exports @sentry/react and @sentry/node as the platform standard for error capture and monitoring via Sentry (self-hosted GlitchTip). The value is standards and drift prevention, not a custom abstraction — per ADR-014, the library’s own API is the interface.


Introduction

Overview

Per ADR-014 (Open Source First), we designate @sentry/react and @sentry/node as the community libraries for error tracking and ship them through @dmwd-io/error-tracking — a thin re-export package. Apps import from @dmwd-io/error-tracking rather than directly from the Sentry SDK, giving the platform a single choke point for version management and drift prevention. Platform conventions documented here include the standard env var names (SENTRY_DSN, SENTRY_ENVIRONMENT), the self-hosted GlitchTip backend per ADR-027 §5, and recommended beforeSend hooks for secret/PII stripping. No custom ErrorTrackingProvider interface is built — the Sentry SDK’s own API is the interface.

Goals

  • Designate @sentry/react and @sentry/node as the platform standard for error capture per ADR-014.
  • Ship @dmwd-io/error-tracking as a thin re-export of the Sentry SDK.
  • Document SENTRY_DSN and SENTRY_ENVIRONMENT as the canonical platform env var names.
  • Document the recommended beforeSend hook pattern for secret/PII stripping.
  • Ensure all apps point to the self-hosted GlitchTip instance per ADR-027 §5.
  • Include release and environment metadata on every reported error for triage.

Non-Goals

  • Bugsnag or Rollbar adapters (not designated by ADR-027; use GlitchTip/Sentry protocol per ADR-027 §5).
  • Implementing error dashboards or alerting rules.
  • Performance monitoring or transaction tracing (see FRD: Tracing / OTel Wrapper).
  • Client-side session replay.
  • Server-side error capture middleware for specific frameworks.
  • Building a custom provider interface or adapter layer — the library’s own API is the interface (per ADR-014).

Scope

In Scope

AreaDescription
@dmwd-io/error-tracking packageThin re-export of @sentry/react and @sentry/node; the single import point for all apps
Platform env varsSENTRY_DSN and SENTRY_ENVIRONMENT documented as canonical names
beforeSend stripping patternRecommended hook removing keys matching secret, password, token, apiKey, authorization, email, phone, ssn, creditCard
GlitchTip backendSelf-hosted Sentry-protocol backend per ADR-027 §5; DSN configured via SENTRY_DSN
MetadataRelease version and environment attached to every error via Sentry.init() options

Out of Scope

AreaReason
Custom ErrorTrackingProvider interfaceADR-014: library API is the interface; no custom abstraction needed
Bugsnag or Rollbar adaptersNot designated by ADR-027; GlitchTip/Sentry protocol is the standard
Error dashboards / alertingVendor-hosted
Performance monitoringCovered by FRD: Tracing / OTel Wrapper
Session replayVendor-specific feature
Server-side middlewareFramework-specific; apps wire their own middleware

Users and Pain Points

User Groups

UserDescriptionNeeds
App developersEngineers building production appsConsistent error capture that works across vendors
QA engineersTesters validating error handlingMock adapter to assert errors are captured correctly
SRE / on-call engineersResponders triaging production errorsConsistent metadata (release, environment, user context) on every error

Pain Points

UserPain PointImpact
App developersEach app wires Sentry differently — some set user context, some do notInconsistent error triage; some errors lack critical context
App developersNo shared React error boundary — each app writes its ownUncaught errors crash the entire app with no recovery UI
SRE engineersSecrets and PII appear in error reportsSecurity and privacy violations; error tracking dashboards become sensitive data stores
App developersNo test path for error capture — tests cannot assert that errors are reportedError reporting regressions go undetected

Definitions

TermDefinition
Exception captureReporting a caught or uncaught Error object to the error tracking service
Message captureReporting a text message (not an Error) at a specified severity level
Error contextKey-value metadata attached to an error report (user, request, custom data)
Secret strippingRemoving keys whose names indicate sensitive values (passwords, tokens, API keys) from error context
Error boundaryA React component that catches JavaScript errors in its subtree and renders a fallback UI
ReleaseA version identifier (e.g. v1.2.3 or git SHA) attached to error reports for regression detection

Current State

Existing Behavior

No shared error tracking abstraction exists. Apps import Sentry SDK directly in their entry points and sprinkle Sentry.captureException() calls in catch blocks. Some apps set user context, some do not. No React error boundary is shared — each app copies a basic implementation from a template. Secret stripping is not systematic.

Current Limitations

  • No shared TypeScript types for error capture operations.
  • No mock adapter — tests cannot verify error reporting.
  • No automatic secret/PII stripping — sensitive data leaks into error reports.
  • No shared React error boundary — each app writes its own or has none.
  • No standard release/environment metadata — some errors lack version info, making regression detection harder.

Existing Workarounds

  • Apps call Sentry.init() in their entry points and Sentry.captureException() in catch blocks.
  • React error boundaries are copy-pasted from a template repo.
  • Developers manually redact sensitive data before calling captureException().

Proposed Solution

Summary

Per ADR-014 (Open Source First), @dmwd-io/error-tracking re-exports @sentry/react and @sentry/node directly — no custom interface is built. Apps import from the package alias and get the full Sentry SDK API. The package documents platform conventions: env var names, beforeSend stripping patterns, and the self-hosted GlitchTip backend.

import { init, captureException, ErrorBoundary } from '@dmwd-io/error-tracking';
init({
dsn: process.env.SENTRY_DSN,
environment: process.env.SENTRY_ENVIRONMENT,
release: process.env.npm_package_version,
beforeSend(event) {
// platform-standard stripping hook — see docs
return stripSensitiveKeys(event);
},
});

No custom interface is built — the library’s API is the interface.

Key Capabilities

  • Full @sentry/react and @sentry/node SDK available via the @dmwd-io/error-tracking import alias.
  • SENTRY_DSN and SENTRY_ENVIRONMENT documented as the canonical platform env var names.
  • Recommended beforeSend hook for secret/PII stripping documented and exported as a utility.
  • <ErrorBoundary> re-exported from @sentry/react for consistent error boundary usage.
  • Self-hosted GlitchTip backend per ADR-027 §5; Sentry-protocol compatible.

User Experience

End users see a graceful fallback UI when errors occur instead of a blank screen. Their PII is protected from appearing in error tracking dashboards via the beforeSend stripping hook.

Developer Experience

Developers import from @dmwd-io/error-tracking and call Sentry.init() once in their app entry point using the platform env vars. The package re-exports the full SDK, so no vendor import changes are needed in existing code — only the import path changes.


Requirements

IDRequirementPriorityNotes
FR-001@dmwd-io/error-tracking re-exports all public APIs from @sentry/react and @sentry/nodeMust-
FR-002SENTRY_DSN and SENTRY_ENVIRONMENT documented as canonical env var namesMust-
FR-003beforeSend stripping utility exported for secret/PII removalMustRemoves secret, password, token, apiKey, authorization, email, phone, ssn, creditCard
FR-004<ErrorBoundary> re-exported from @sentry/reactMust-
FR-005Release and environment metadata pattern documented with exampleShould-

Priority Definitions

PriorityMeaning
MustRequired for this feature to ship.
ShouldImportant, but can be deferred if needed.
CouldNice to have. Not required for initial release.

Functional Requirements

IDRequirementUser BenefitPriority
FUNC-001captureException(error, { orderId: "123" }) works via the re-exported SDKConsistent error reporting from catch blocksMust
FUNC-002captureMessage("Rate limit exceeded", "warning") works via the re-exported SDKNon-exception events tracked for observabilityShould
FUNC-003setUser({ id, email, role }) works via the re-exported SDKEvery error report includes who was affectedMust
FUNC-004<ErrorBoundary fallback={<ErrorPage />}> catches uncaught errors and reports themGraceful degradation instead of blank screenMust
FUNC-005beforeSend stripping hook removes apiKey, password, email, phone from event dataSecrets never reach the error tracking vendorMust
FUNC-006clearUser() removes user context for subsequent errors (e.g. on sign-out)No stale user association after sign-outShould

Non-Functional Requirements

IDRequirementCategoryPriority
NFR-001captureException never throws — errors in the error tracker must not crash the appReliabilityMust
NFR-002No custom wrapper layer between app code and the Sentry SDKMaintainabilityMust
NFR-003Secret/PII stripping scans nested objects up to 3 levels deepSecurityMust
NFR-004Package adds no runtime dependencies beyond @sentry/react and @sentry/nodePerformanceMust
NFR-005<ErrorBoundary> recovers from errors without requiring a page reload (reset on retry)ReliabilityShould

API / Interface Requirements

Public API

NameTypeDescriptionRequired
All @sentry/react exportsre-exportFull SDK surface: init, captureException, captureMessage, setUser, setContext, ErrorBoundary, etc.Yes
All @sentry/node exportsre-exportFull SDK surface for server-side usageYes
stripSensitiveKeysfunction(event: SentryEvent) => SentryEvent — removes sensitive keys for use in beforeSendYes

Example Usage

import { init, captureException, ErrorBoundary } from '@dmwd-io/error-tracking';
// App entry point
init({
dsn: process.env.SENTRY_DSN,
environment: process.env.SENTRY_ENVIRONMENT,
release: process.env.npm_package_version,
beforeSend: stripSensitiveKeys,
});
// Catch block
try {
await riskyOperation();
} catch (error) {
captureException(error, { extra: { orderId: 'ord_456' } });
}
// React tree
<ErrorBoundary fallback={<ErrorPage />}>
<App />
</ErrorBoundary>

API Notes

  • All Sentry SDK methods are available without modification — the package is a pure re-export.
  • stripSensitiveKeys is a beforeSend-compatible hook, not a standalone stripping utility. Pass it directly to init({ beforeSend }).
  • <ErrorBoundary> is the Sentry-provided component from @sentry/react; it accepts fallback and onError props.
  • Apps should call init() once at the entry point; subsequent imports of captureException etc. use the initialized SDK instance.

Accessibility Requirements

IDRequirementNotes
A11Y-001<ErrorBoundary> fallback UI must be keyboard navigableUsers must be able to interact with the error fallback
A11Y-002Fallback UI should announce the error state to screen readers via role="alert"Screen reader users are informed of the error
A11Y-003”Try again” / reset action must be focusable and labeledRecovery action is accessible

Checklist

  • Keyboard support is defined. (ErrorBoundary fallback must be keyboard navigable)
  • Focus behavior is defined. (Focus moves to fallback when error occurs)
  • Screen reader behavior is defined. (role="alert" on fallback)
  • Color contrast requirements are met. (Fallback UI follows design system tokens)
  • Reduced motion behavior is considered. (No animation in error fallback)
  • Semantic HTML expectations are documented. (Fallback uses semantic heading + paragraph)
  • ARIA usage is defined only where needed. (role="alert" only)

Content and Documentation Requirements

IDRequirementLocationPriority
DOC-001Storybook docs page explaining the re-export pattern and platform env var conventionsStorybookMust
DOC-002Inline JSDoc on stripSensitiveKeysSource codeMust
DOC-003Example: <ErrorBoundary> wrapping a component that throwsStorybookMust
DOC-004Example: init() with SENTRY_DSN, SENTRY_ENVIRONMENT, and beforeSend strippingStorybookMust
DOC-005Example: secret/PII stripping via beforeSendStorybookShould

Dependencies

DependencyTypeOwnerStatusNotes
ADR-051 provider patternArchitectureEngineeringReadyDefines contract structure
ADR-023 wide events loggingArchitectureEngineeringReadyErrors should correlate with log events
ADR-027 default tech stackArchitectureEngineeringReadyDesignates GlitchTip (Sentry-protocol compatible, self-hosted) as the error tracking default
ADR-014 open source firstArchitectureEngineeringReadyDesignates community library as the interface; no custom adapter needed
React (peer dependency)RuntimeReact teamReadyRequired for <ErrorBoundary>

Risks and Tradeoffs

Risk / TradeoffImpactMitigation
Never-throw contract means error tracking failures are silentMissing error reports go unnoticedLog tracking failures to console in dev mode
3-level deep secret stripping may miss deeply nested secretsIncomplete strippingDocument the depth limit; apply additional stripping in beforeSend if needed
<ErrorBoundary> only catches render-phase errors, not event handler errorsEvent handler errors require explicit captureException callsDocument this limitation clearly
PII stripping may be too aggressive — email field in a notification context could be intentionalData lossAllow per-call opt-out by not passing beforeSend to captureException context
Thin re-export means apps are coupled to the Sentry SDK API surfaceSDK upgrades require app-level changesPin SDK version in @dmwd-io/error-tracking; control upgrades centrally

Open Questions

IDQuestionOwnerStatusResolution
Q-001Should the <ErrorBoundary> support automatic retry (re-render children after a delay)?David HolmesOpen
Q-002Should the provider include breadcrumbs (a trail of recent actions leading to the error)?David HolmesOpen
Q-003Should captureException accept a fingerprint for custom error grouping?David HolmesOpen

Acceptance Criteria

IDCriteriaRelated Requirement
AC-001@dmwd-io/error-tracking exports all public APIs from @sentry/react and @sentry/nodeFR-001
AC-002<ErrorBoundary> catches a thrown error and renders the fallback UIFR-004
AC-003<ErrorBoundary> calls captureException on the Sentry SDK when an error is caughtFR-004
AC-004stripSensitiveKeys removes apiKey, password, email, phone from event dataFR-003
AC-005SENTRY_DSN and SENTRY_ENVIRONMENT are documented as the canonical env var namesFR-002
AC-006No custom ErrorTrackingProvider interface is shippedNFR-002
AC-007captureException never throws, even when the SDK’s internal logic failsNFR-001
AC-008Unit tests cover stripSensitiveKeys at 1, 2, and 3 levels of nestingFR-003
AC-009Storybook docs page shows init() with platform env vars and beforeSend hookDOC-001

LLM Handoff Instructions

Expected LLM Behavior

  • Create a packages/error-tracking/ directory (or equivalent monorepo package location).
  • Add a package.json with name @dmwd-io/error-tracking, listing @sentry/react and @sentry/node as peer dependencies.
  • Create src/index.ts that re-exports everything: export * from '@sentry/react' and export * from '@sentry/node'.
  • Export stripSensitiveKeys as a named export — a beforeSend-compatible function that removes keys matching secret, password, token, apiKey, authorization, email, phone, ssn, creditCard up to 3 levels deep.
  • Document SENTRY_DSN and SENTRY_ENVIRONMENT as the canonical env var names in the package README and Storybook docs page.
  • Run pnpm typecheck to confirm the package compiles cleanly.

LLM Should Not

  • Build a custom ErrorTrackingProvider interface or adapter layer — the Sentry SDK’s API is the interface per ADR-014.
  • Import Bugsnag or Rollbar SDKs. Do not use Sentry SaaS — use the Sentry SDK pointing to the self-hosted GlitchTip instance per ADR-027.
  • Add runtime dependencies beyond @sentry/react and @sentry/node.
  • Wrap captureException in a custom function — re-export it directly.
  • Skip the stripSensitiveKeys utility — it is a security requirement.

Decision Log

DateDecisionReasonOwner
2026-05-26Never-throw contract for all capture methodsError tracking must not make errors worse; a throwing error tracker is a liabilityDavid Holmes
2026-05-263-level deep secret scanningBalances thoroughness with performance; most contexts are 1-2 levels deepDavid Holmes
2026-05-26Export stripSensitiveKeys as a public utilityUseful for logging, analytics, and other providers that handle sensitive contextDavid Holmes
2026-05-26GlitchTip designated as the error tracking backendADR-027 §5 designates GlitchTip (Sentry-protocol compatible) as the error tracking default; uses the Sentry SDK for client compatibilityDavid Holmes
2026-06-02Reframed per ADR-014 (Open Source First): adopt @sentry/react / @sentry/node as thin re-export rather than building a custom provider interface. Library API is the interface.ADR-014 requires designating a community library over custom abstractions when one existsDavid Holmes

Document History

DateAuthorChange
2026-05-26David HolmesInitial draft
2026-06-02David HolmesReframed per ADR-014: ship as thin re-export of @sentry/react / @sentry/node, drop custom interface.