# 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.