-
-
Notifications
You must be signed in to change notification settings - Fork 1.8k
Expand file tree
/
Copy pathhono.ts
More file actions
107 lines (92 loc) · 3.36 KB
/
Copy pathhono.ts
File metadata and controls
107 lines (92 loc) · 3.36 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
import type { IntegrationFn } from '@sentry/core';
import {
captureException,
debug,
defineIntegration,
getActiveSpan,
getClient,
getIsolationScope,
getRootSpan,
updateSpanName,
} from '@sentry/core';
import { DEBUG_BUILD } from '../debug-build';
const INTEGRATION_NAME = 'Hono' as const;
interface HonoError extends Error {
status?: number;
}
// Minimal type - only exported for tests
export interface HonoContext {
req: { method: string; path?: string };
}
export interface Options {
/**
* Callback method deciding whether error should be captured and sent to Sentry
* @param error Captured middleware error
*/
shouldHandleError?(this: void, error: HonoError): boolean;
}
/** Only exported for internal use */
export function getHonoIntegration(): ReturnType<typeof _honoIntegration> | undefined {
return getClient()?.getIntegrationByName(INTEGRATION_NAME);
}
function isHonoError(err: unknown): err is HonoError {
if (err instanceof Error) {
return true;
}
return typeof err === 'object' && err !== null && 'status' in (err as Record<string, unknown>);
}
// Vendored from https://github.com/honojs/hono/blob/d3abeb1f801aaa1b334285c73da5f5f022dbcadb/src/helper/route/index.ts#L58-L59
const routePath = (c: HonoContext): string => c.req?.path ?? '';
const _honoIntegration = ((options: Partial<Options> = {}) => {
return {
name: INTEGRATION_NAME,
// Hono error handler: https://github.com/honojs/hono/blob/d3abeb1f801aaa1b334285c73da5f5f022dbcadb/src/hono-base.ts#L35
handleHonoException(err: HonoError, context: HonoContext): void {
const shouldHandleError = options.shouldHandleError || defaultShouldHandleError;
if (!isHonoError(err)) {
DEBUG_BUILD && debug.log("[Hono] Won't capture exception in `onError` because it's not a Hono error.", err);
return;
}
if (shouldHandleError(err)) {
if (context) {
const activeSpan = getActiveSpan();
const spanName = `${context.req.method} ${routePath(context)}`;
if (activeSpan) {
activeSpan.updateName(spanName);
updateSpanName(getRootSpan(activeSpan), spanName);
}
getIsolationScope().setTransactionName(spanName);
}
captureException(err, { mechanism: { handled: false, type: 'auto.faas.hono.error_handler' } });
} else {
DEBUG_BUILD && debug.log('[Hono] Not capturing exception because `shouldHandleError` returned `false`.', err);
}
},
};
}) satisfies IntegrationFn;
/**
* Automatically captures exceptions caught with the `onError` handler in Hono.
*
* The integration is enabled by default.
*
* @deprecated Use the `@sentry/hono` package instead. The `sentry()` middleware from `@sentry/hono/cloudflare`
* handles error capturing automatically without needing this integration.
*
* @example
* integrations: [
* honoIntegration({
* shouldHandleError: (err) => true; // always capture exceptions in onError
* })
* ]
*/
export const honoIntegration = defineIntegration(_honoIntegration);
/**
* Default function to determine if an error should be sent to Sentry
*
* 3xx and 4xx errors are not sent by default.
*/
function defaultShouldHandleError(error: HonoError): boolean {
const statusCode = error?.status;
// 3xx and 4xx errors are not sent by default.
return statusCode ? statusCode >= 500 || statusCode <= 299 : true;
}