All Docs
FeaturesCalmony Sanctions MonitorUpdated March 12, 2026

Error Monitoring with Sentry

Error Monitoring with Sentry

As of v0.1.122, the platform uses Sentry (@sentry/nextjs) as its production error monitoring service. This replaces the previous behaviour where server-side errors were only written to console.error — which is ephemeral in serverless environments and invisible to operators.

Why This Matters

The sanctions screening platform performs critical background operations:

  • Nightly OFSI sync — downloading and diffing the UK consolidated sanctions list.
  • Stripe billing operations — subscription creation, webhook handling.
  • Database queries — screening results, audit logs, user records.

Failures in any of these operations were previously silent in production. With Sentry configured, every unhandled exception in an API route is captured with full context (user ID, request path, stack trace) and surfaced in the Sentry dashboard in real time.

Architecture

FilePurpose
sentry.client.config.tsInitialises Sentry in the browser using NEXT_PUBLIC_SENTRY_DSN
sentry.server.config.tsInitialises Sentry on the server (Node.js / Edge runtimes)
instrumentation.tsNext.js instrumentation hook — bootstraps server-side capture on cold start
src/lib/capture-error.tsInternal captureError() utility — now proxies to Sentry.captureException()

Configuration

1. Create a Sentry Project

  1. Log in to sentry.io and create a new project.
  2. Select Next.js as the platform.
  3. Copy the DSN from Project Settings → Client Keys (DSN).

2. Set the Environment Variable

Add the following to your .env.local (development) and your production environment secrets:

NEXT_PUBLIC_SENTRY_DSN=https://<key>@o<org>.ingest.sentry.io/<project-id>

Note: This variable is prefixed with NEXT_PUBLIC_ so it is available to the client-side Sentry initialisation. It is not a secret — DSNs are safe to expose in client bundles.

3. Verify the Integration

Once deployed, trigger a test error by calling the Sentry test endpoint (if enabled) or by temporarily throwing in a known route. Confirm the event appears in your Sentry project dashboard within a few seconds.

How Errors Are Captured

All API route catch blocks now call:

import * as Sentry from '@sentry/nextjs';

catch (error) {
  Sentry.captureException(error, {
    extra: {
      userId,
      path,
    },
  });
  return NextResponse.json({ error: 'Internal Server Error' }, { status: 500 });
}

The captureError() utility in src/lib/capture-error.ts also proxies to Sentry.captureException(), so any existing internal calls continue to work and now route to Sentry.

What Is Captured

  • Database failures (connection errors, query errors)
  • Stripe API errors (payment failures, webhook processing errors)
  • OFSI sync failures (download errors, parse errors, diff errors)
  • Any unhandled exception in an API route handler

Sentry Context

Each captured exception includes:

FieldValue
extra.userIdThe authenticated user's ID at the time of the error
extra.pathThe API route path that threw the error
Stack traceFull server-side stack trace
Environmentdevelopment / production (set by SENTRY_ENVIRONMENT or Next.js defaults)

Environments and Filtering

Sentry will receive errors from all environments by default. To restrict alerts to production only, configure alert rules in your Sentry project to filter by environment = production.

Related