honojs-middleware/packages/sentry/src/index.ts

55 lines
1.3 KiB
TypeScript
Raw Normal View History

import type { Context, MiddlewareHandler } from 'hono'
2022-08-04 07:29:03 +08:00
import Toucan from 'toucan-js'
import type { Options as ToucanOptions } from 'toucan-js'
2022-08-04 07:54:30 +08:00
2022-08-12 11:41:03 +08:00
declare module 'hono' {
interface ContextVariableMap {
sentry: Toucan
}
}
2022-08-12 11:41:03 +08:00
class MockContext implements ExecutionContext {
passThroughOnException(): void {
throw new Error('Method not implemented.')
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
2022-08-12 11:41:03 +08:00
async waitUntil(promise: Promise<any>): Promise<void> {
await promise
}
}
export type Options = Omit<ToucanOptions, 'request' | 'context'>
2022-08-11 23:37:53 +08:00
export const sentry = (
options?: Options,
callback?: (sentry: Toucan) => void
): MiddlewareHandler => {
2022-08-04 07:54:30 +08:00
return async (c, next) => {
2022-08-12 11:41:03 +08:00
let hasExecutionContext = true
try {
c.executionCtx
} catch {
hasExecutionContext = false
}
2022-08-04 07:29:03 +08:00
const sentry = new Toucan({
dsn: c.env?.SENTRY_DSN ?? c.env?.NEXT_PUBLIC_SENTRY_DSN,
2022-08-04 07:29:03 +08:00
allowedHeaders: ['user-agent'],
allowedSearchParams: /(.*)/,
request: c.req.raw,
2022-08-12 11:41:03 +08:00
context: hasExecutionContext ? c.executionCtx : new MockContext(),
2022-08-11 23:37:53 +08:00
...options,
2022-08-04 07:29:03 +08:00
})
2022-09-03 01:11:34 +08:00
c.set('sentry', sentry)
2022-08-11 23:37:53 +08:00
if (callback) callback(sentry)
await next()
if (c.error) {
sentry.captureException(c.error)
2022-08-04 07:29:03 +08:00
}
2022-08-04 07:54:30 +08:00
}
}
2022-08-12 11:41:03 +08:00
export const getSentry = (c: Context) => {
return c.get('sentry')
}