fix(plugin-sentry): capture non APIError errors to sentry (#9595)
Previously, non Payload errors (that aren't `APIError`, for example from `throw new Error()`) weren't captured to Sentry
This commit is contained in:
@@ -53,38 +53,36 @@ export const sentryPlugin =
|
||||
afterError: [
|
||||
...(config.hooks?.afterError ?? []),
|
||||
async (args) => {
|
||||
if ('status' in args.error) {
|
||||
const apiError = args.error as APIError
|
||||
if (apiError.status >= 500 || captureErrors.includes(apiError.status)) {
|
||||
let context: Partial<ScopeContext> = {
|
||||
extra: {
|
||||
errorCollectionSlug: args.collection?.slug,
|
||||
const status = (args.error as APIError).status ?? 500
|
||||
if (status >= 500 || captureErrors.includes(status)) {
|
||||
let context: Partial<ScopeContext> = {
|
||||
extra: {
|
||||
errorCollectionSlug: args.collection?.slug,
|
||||
},
|
||||
...(args.req.user && {
|
||||
user: {
|
||||
id: args.req.user.id,
|
||||
collection: args.req.user.collection,
|
||||
email: args.req.user.email,
|
||||
ip_address: args.req.headers?.get('X-Forwarded-For') ?? undefined,
|
||||
username: args.req.user.username,
|
||||
},
|
||||
...(args.req.user && {
|
||||
user: {
|
||||
id: args.req.user.id,
|
||||
collection: args.req.user.collection,
|
||||
email: args.req.user.email,
|
||||
ip_address: args.req.headers?.get('X-Forwarded-For') ?? undefined,
|
||||
username: args.req.user.username,
|
||||
},
|
||||
}),
|
||||
}
|
||||
}),
|
||||
}
|
||||
|
||||
if (options?.context) {
|
||||
context = await options.context({
|
||||
...args,
|
||||
defaultContext: context,
|
||||
})
|
||||
}
|
||||
if (options?.context) {
|
||||
context = await options.context({
|
||||
...args,
|
||||
defaultContext: context,
|
||||
})
|
||||
}
|
||||
|
||||
const id = Sentry.captureException(args.error, context)
|
||||
const id = Sentry.captureException(args.error, context)
|
||||
|
||||
if (debug) {
|
||||
args.req.payload.logger.info(
|
||||
`Captured exception ${id} to Sentry, error msg: ${args.error.message}`,
|
||||
)
|
||||
}
|
||||
if (debug) {
|
||||
args.req.payload.logger.info(
|
||||
`Captured exception ${id} to Sentry, error msg: ${args.error.message}`,
|
||||
)
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@@ -61,7 +61,29 @@ describe('@payloadcms/plugin-sentry - unit', () => {
|
||||
|
||||
const hook = config.hooks?.afterError?.[0] as AfterErrorHook
|
||||
|
||||
const error = new APIError('ApiError', 500)
|
||||
const apiError = new Error('ApiError')
|
||||
|
||||
const afterApiErrorHookArgs: AfterErrorHookArgs = {
|
||||
req: {} as PayloadRequest,
|
||||
context: {},
|
||||
error: apiError,
|
||||
collection: { slug: 'mock-slug' } as any,
|
||||
}
|
||||
|
||||
const captureExceptionSpy = jest.spyOn(mockSentry, 'captureException')
|
||||
|
||||
await hook(afterApiErrorHookArgs)
|
||||
|
||||
expect(captureExceptionSpy).toHaveBeenCalledTimes(1)
|
||||
expect(captureExceptionSpy).toHaveBeenCalledWith(apiError, {
|
||||
extra: {
|
||||
errorCollectionSlug: 'mock-slug',
|
||||
hintTimestamp,
|
||||
},
|
||||
})
|
||||
expect(captureExceptionSpy).toHaveReturnedWith(mockExceptionID)
|
||||
|
||||
const error = new Error('Error')
|
||||
|
||||
const afterErrorHookArgs: AfterErrorHookArgs = {
|
||||
req: {} as PayloadRequest,
|
||||
@@ -70,11 +92,9 @@ describe('@payloadcms/plugin-sentry - unit', () => {
|
||||
collection: { slug: 'mock-slug' } as any,
|
||||
}
|
||||
|
||||
const captureExceptionSpy = jest.spyOn(mockSentry, 'captureException')
|
||||
|
||||
await hook(afterErrorHookArgs)
|
||||
|
||||
expect(captureExceptionSpy).toHaveBeenCalledTimes(1)
|
||||
expect(captureExceptionSpy).toHaveBeenCalledTimes(2)
|
||||
expect(captureExceptionSpy).toHaveBeenCalledWith(error, {
|
||||
extra: {
|
||||
errorCollectionSlug: 'mock-slug',
|
||||
|
||||
Reference in New Issue
Block a user