# Sentry Express: skip the old two-middleware dance

## Current pattern

```js
const Sentry = require("@sentry/node");

Sentry.init({
  dsn: "___PUBLIC_DSN___",
  integrations: [
    Sentry.expressIntegration({
      shouldHandleError(error) {
        const status = Number(error.status ?? error.statusCode ?? 500);
        return status === 401 || status === 403 || status >= 500;
      },
    }),
  ],
});
```

`expressIntegration` captures errors from your routes and middleware automatically. You do not need to register a separate Sentry error handler anymore. Training data that tells you to add `Sentry.Handlers.requestHandler()` and `Sentry.Handlers.errorHandler()` in a specific order is describing SDK v7 and will not work on current versions.

## What gets skipped

Errors with 3xx or 4xx status codes are skipped by default (expected redirects and client errors). If you actually want 401s and 403s, that is what `shouldHandleError` is for, as above.

## The duplicate-event trap

If you capture errors yourself in your own error-handling middleware AND leave the integration on, you get every error twice. Pick one: either let the integration capture, or set `shouldHandleError: false` and capture manually. Duplicates are one of the most common quota leaks in Express apps.

## Ordering still matters for init

The integration instruments what it sees. Keep the `node --import ./instrument.js` preload pattern from the Node.js skill so `Sentry.init()` runs before Express and your routes load.