-
-
Notifications
You must be signed in to change notification settings - Fork 1.8k
feat(express)!: Remove shouldHandleError from setupExpressErrorHandler
#23732
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -53,7 +53,7 @@ export { vercelAIIntegration } from './integrations/vercel-ai'; | |
| export { expressIntegration } from './integrations/express'; | ||
| /* oxlint-disable typescript/no-deprecated -- deprecated Express error-handler exports, kept until the next major */ | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't think any deprecated items are being pulled in here, are they? It's the one in core that's deprecated, this one isn't. |
||
| export { expressErrorHandler, setupExpressErrorHandler } from './integrations/express/error-handler'; | ||
| export type { ExpressHandlerOptions } from './integrations/express/types'; | ||
| export type { ExpressIntegrationOptions } from './integrations/express/types'; | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is a bit minor, but could be confusing. The core version is deprecated, and doesn't have This can certainly be cleaned up in a followup, but I think it would be best to coalesce these into a single type (either defined in core, or here, but not both). |
||
| /* oxlint-enable typescript/no-deprecated */ | ||
| export { firebaseIntegration } from './integrations/firebase'; | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -1,7 +1,7 @@ | ||||||
| import { captureException, getIsolationScope, httpRequestToRequestData } from '@sentry/core'; | ||||||
| import { captureException, getClient, getIsolationScope, httpRequestToRequestData } from '@sentry/core'; | ||||||
| import { isExpressErrorHandled } from './error-handled'; | ||||||
| import type { ExpressHandlerOptions, ExpressRequest, ExpressResponse, MiddlewareError } from './types'; | ||||||
| import { defaultShouldHandleError } from './utils'; | ||||||
| import type { ExpressIntegration, ExpressRequest, ExpressResponse, MiddlewareError } from './types'; | ||||||
| import { INTEGRATION_NAME, shouldCaptureError } from './utils'; | ||||||
|
|
||||||
| type ExpressErrorMiddleware = ( | ||||||
| error: MiddlewareError, | ||||||
|
|
@@ -12,6 +12,10 @@ type ExpressErrorMiddleware = ( | |||||
|
|
||||||
| type ExpressMiddleware = (request: ExpressRequest, res: ExpressResponse, next: () => void) => void; | ||||||
|
|
||||||
| function getExpressIntegration(): ExpressIntegration | undefined { | ||||||
| return getClient()?.getIntegrationByName<ExpressIntegration>(INTEGRATION_NAME); | ||||||
| } | ||||||
|
|
||||||
| /** | ||||||
| * Set request data on the isolation scope so a captured error carries request context. Mirrors the | ||||||
| * request handler middleware, which does not run once an error short-circuits the middleware chain. | ||||||
|
|
@@ -30,7 +34,7 @@ function setSDKProcessingMetadata(request: ExpressRequest): void { | |||||
| * @deprecated `expressIntegration()` now captures errors automatically. This export is deprecated and | ||||||
| * will be removed in the next major version. | ||||||
| */ | ||||||
| export function expressErrorHandler(options?: ExpressHandlerOptions): ExpressErrorMiddleware { | ||||||
| export function expressErrorHandler(): ExpressErrorMiddleware { | ||||||
| return function sentryErrorMiddleware(error, request, res, next): void { | ||||||
| // When an error happens, the request handler middleware does not run, so we set it here too. | ||||||
| setSDKProcessingMetadata(request); | ||||||
|
|
@@ -45,9 +49,9 @@ export function expressErrorHandler(options?: ExpressHandlerOptions): ExpressErr | |||||
| return; | ||||||
| } | ||||||
|
|
||||||
| const shouldHandleError = options?.shouldHandleError || defaultShouldHandleError; | ||||||
|
|
||||||
| if (shouldHandleError(error)) { | ||||||
| // `shouldHandleError` is configured on `expressIntegration()` only. Without the integration | ||||||
| // registered, the default predicate applies. | ||||||
| if (shouldCaptureError(getExpressIntegration()?.getShouldHandleError(), error)) { | ||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
Unlikely edge case, but if the |
||||||
| const eventId = captureException(error, { | ||||||
| mechanism: { type: 'auto.middleware.express', handled: false }, | ||||||
| }); | ||||||
|
|
@@ -71,20 +75,16 @@ function expressRequestHandler(): ExpressMiddleware { | |||||
| * The error handler must be before any other middleware and after all controllers. | ||||||
| * | ||||||
| * @param app The Express instance | ||||||
| * @param options {ExpressHandlerOptions} Configuration options for the handler | ||||||
| * | ||||||
| * @deprecated `expressIntegration()` now captures errors automatically, so calling this is no longer | ||||||
| * necessary. To customize which errors are captured, pass `shouldHandleError` to `expressIntegration()`. | ||||||
| * This export is deprecated and will be removed in the next major version. | ||||||
| */ | ||||||
| export function setupExpressErrorHandler( | ||||||
| app: { | ||||||
| // oxlint-disable-next-line no-explicit-any | ||||||
| use: (middleware: any) => unknown; | ||||||
| }, | ||||||
| options?: ExpressHandlerOptions, | ||||||
| ): void { | ||||||
| export function setupExpressErrorHandler(app: { | ||||||
| // oxlint-disable-next-line no-explicit-any | ||||||
| use: (middleware: any) => unknown; | ||||||
| }): void { | ||||||
| app.use(expressRequestHandler()); | ||||||
| // oxlint-disable-next-line typescript/no-deprecated | ||||||
| app.use(expressErrorHandler(options)); | ||||||
| app.use(expressErrorHandler()); | ||||||
| } | ||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,4 +1,8 @@ | ||
| import type { MiddlewareError } from './types'; | ||
| import type { ExpressShouldHandleError, MiddlewareError } from './types'; | ||
|
|
||
| // NOTE: this uses the same name as the OTel integration by design. | ||
| // When enabled, the OTel 'Express' integration is omitted from the default set. | ||
| export const INTEGRATION_NAME = 'Express' as const; | ||
|
|
||
| function getStatusCodeFromResponse(error: MiddlewareError): number { | ||
| const statusCode = error.status || error.statusCode || error.status_code || error.output?.statusCode; | ||
|
|
@@ -13,3 +17,19 @@ function getStatusCodeFromResponse(error: MiddlewareError): number { | |
| export function defaultShouldHandleError(error: MiddlewareError): boolean { | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. low: Does anything else use this? If it's only used internally, I don't think we still need to export it. |
||
| return getStatusCodeFromResponse(error) >= 500; | ||
| } | ||
|
|
||
| /** | ||
| * Apply the configured `shouldHandleError`: `false` turns capture off entirely, a function replaces | ||
| * the gate, and `undefined` falls back to {@link defaultShouldHandleError}. Both the integration and | ||
| * the deprecated middleware go through here, so they always agree. | ||
| */ | ||
| export function shouldCaptureError( | ||
| shouldHandleError: ExpressShouldHandleError | undefined, | ||
| error: MiddlewareError, | ||
| ): boolean { | ||
| if (shouldHandleError === false) { | ||
| return false; | ||
| } | ||
|
|
||
| return (shouldHandleError ?? defaultShouldHandleError)(error); | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
low:
error.statusCodecan be a string.