Profiles·Public

@sentry/node

semver>=7.0.0postconditions11functions8last verified2026-06-24coverage score73%

Postconditions: what we check

  • init · invalid-dsn
    warning
    WhenDSN is missing, malformed, or contains an invalid public key
    ThrowsError or DSN validation failure routed through onFatalError
    Required handlingCaller MUST validate that the DSN env var (typically SENTRY_DSN) is present and non-empty before calling Sentry.init(). For optional telemetry — e.g. local dev — wrap in a try/catch and degrade gracefully (log a warning, continue without Sentry). DO NOT let an invalid DSN throw at module-load time during process boot — it will take down the whole app for a non-essential observability dependency.
    costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[1][2]
  • flush · flush-return-ignored
    warning
    Whenflush() return value is ignored — caller proceeds assuming success
    ReturnsPromise<boolean> where false = timeout, events lost
    Required handlingCaller MUST check the return value of await Sentry.flush(timeout). If false, events did not deliver within the timeout — log this fact (to stdout, not Sentry — Sentry is the thing that failed). Common mistake: writing `await Sentry.flush(2000); process.exit(0)` and assuming events landed. They didn't if flush returned false. For worker / serverless shutdown paths this is the difference between "lost the smoking-gun error log" and "captured the crash."
    costmediumin prodsilent failureusers seedegraded performancevisibilitysilent
    Sources[3][4]
  • flush · flush-not-awaited
    error
    WhenProcess exits before queued Sentry events are sent
    ReturnsPromise<boolean>
    Required handlingCaller MUST await Sentry.flush() (or Sentry.close()) before any deliberate process.exit() in worker / cron / serverless handlers. Fire-and-forget Sentry.captureException() does NOT block; events live in an in-memory queue that drains asynchronously. Exiting the process before drain completes drops the events.
    costmediumin prodsilent failureusers seedegraded performancevisibilitysilent
    Sources[3]
  • close · close-not-awaited
    error
    WhenProcess exits before close() resolves — same shape as flush-not-awaited but harder to retry because close() is one-shot
    ReturnsPromise<boolean>
    Required handlingCaller MUST await Sentry.close(timeout) before deliberate process.exit() in shutdown handlers. Unlike flush(), close() disables future capture — calling captureException() after close() succeeds is a no-op (silent loss). Prefer flush() in long-running processes that just need to drain; reserve close() for true shutdown paths.
    costmediumin prodsilent failureusers seedegraded performancevisibilitysilent
    Sources[3]
  • startSpan · span-callback-rethrows
    warning
    WhenErrors thrown inside the span callback are captured (good) AND re-thrown to the caller (caller must still handle)
    ThrowsWhatever the callback threw
    Required handlingCaller MUST treat Sentry.startSpan() as transparent for error propagation. The span captures the error for observability, but the error still escapes the span call and reaches the caller. If you want Sentry to "swallow" the error, wrap explicitly in try/catch — do not assume startSpan absorbs it. Common misuse: "I put it in a span so it's tracked" while the unhandled rejection crashes the process.
    costlowin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[5]
  • startSpanManual · span-manual-finish-never-called
    error
    Whenfinish() or span.end() is never called — callback returns without ending the span
    ReturnsSpan remains open indefinitely — never sent to Sentry, never recorded
    Required handlingCaller MUST call finish() (the second callback argument) or span.end() in ALL code paths including error paths. The most dangerous pattern is a try/catch that calls finish() only in the happy path — a thrown error exits the callback without finishing the span. Use try/finally: startSpanManual(options, (span, finish) => { try { doWork(); } finally { finish(); } }); Unfinished spans silently vanish: no performance data in Sentry, no error recorded, no alert fired. Debugging "why are my spans missing" is extremely difficult because no error is thrown.
    costlowin prodsilent failureusers seedegraded performancevisibilitysilent
    Sources[5]
  • startSpanManual · span-manual-callback-rethrows
    warning
    WhenErrors thrown inside the startSpanManual callback are re-thrown to the caller (same as startSpan)
    ThrowsWhatever the callback threw
    Required handlingCaller MUST treat Sentry.startSpanManual() as transparent for error propagation. Errors are not swallowed. If the callback throws before calling finish(), the span is never ended AND the error propagates. Always use try/finally to guarantee finish() is called.
    costlowin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[5]
  • startInactiveSpan · inactive-span-end-never-called
    error
    Whenspan.end() is never called — span was created but never finished
    ReturnsSpan remains open indefinitely — never sent to Sentry
    Required handlingCaller MUST call span.end() in ALL code paths. Wrap the work in try/finally to guarantee the span is ended even when errors are thrown: const span = Sentry.startInactiveSpan({ name: 'my-op' }); try { await doWork(); } finally { span.end(); } Because the span is inactive (not in async context), no automatic cleanup mechanism exists. An unended inactive span is permanently lost data — no error is thrown, no warning is logged.
    costlowin prodsilent failureusers seedegraded performancevisibilitysilent
    Sources[5]
  • withMonitor · monitor-callback-rethrows
    warning
    WhenErrors thrown (or rejected Promises returned) by the withMonitor callback propagate to the caller after Sentry records the error check-in
    ThrowsWhatever the callback threw or rejected with
    Required handlingCaller MUST handle errors from Sentry.withMonitor() — the function does NOT swallow errors. The Sentry check-in (status="error") is sent before re-throwing, so the error IS captured by Sentry. But the cron handler code still needs its own try/catch to prevent unhandled rejections from crashing the worker/scheduler. Common mistake: wrapping the entire cron job in withMonitor and assuming that "Sentry handles it." Sentry records the failure; it does not recover from it. The scheduler will see the job as failed.
    costmediumin prodimmediate exceptionusers seedegraded performancevisibilityvisible
    Sources[6][7]
  • withMonitor · monitor-slug-not-configured
    warning
    WhenmonitorSlug does not match an existing monitor in the Sentry project, and upsertMonitorConfig is not provided to auto-create it
    ReturnsCheck-ins are sent but silently ignored by Sentry — no monitor data recorded, no alerts fired
    Required handlingAlways provide upsertMonitorConfig as the third argument to withMonitor() in production environments. The config creates the monitor if it does not exist, ensuring check-ins are recorded. Without it, a typo in the slug or a missing monitor setup causes complete silent loss of cron monitoring with no error thrown. Minimum config: Sentry.withMonitor('my-cron', callback, { schedule: { type: 'crontab', value: '0 * * * *' } });
    costmediumin prodsilent failureusers seedegraded performancevisibilitysilent
    Sources[6]
  • captureCheckIn · checkin-completion-missing
    warning
    WhencaptureCheckIn({ status: 'in_progress' }) is called at job start but the completion check-in (status: 'ok' or 'error') is never sent — e.g., job crashes before the second captureCheckIn call
    ReturnscheckInId (string) — but without the completion check-in, monitor marks run as timed out after maxRuntime
    Required handlingCaller MUST ensure the completion check-in is always sent, even when the job throws. Store the checkInId and wrap the job body in try/catch/finally: const checkInId = Sentry.captureCheckIn({ monitorSlug: 'my-cron', status: 'in_progress' }); try { await runJob(); Sentry.captureCheckIn({ monitorSlug: 'my-cron', status: 'ok', checkInId }); } catch (err) { Sentry.captureCheckIn({ monitorSlug: 'my-cron', status: 'error', checkInId }); throw err; } A missed completion check-in results in a "timed out" alert rather than an "error" alert — making root cause analysis harder.
    costlowin prodsilent failureusers seedegraded performancevisibilitysilent
    Sources[6]

Sources

Every postcondition cites at least one of these. Grouped by source type; numbered to match the footnotes above.

Official documentation
Source code
Need a different package?
Request a profile