@hawk.so/nextjs 1.0.0 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +161 -115
- package/dist/client.js +163 -0
- package/dist/{index.cjs → config.cjs} +82 -45
- package/dist/{index.d.cts → config.d.cts} +1 -1
- package/dist/config.d.ts +75 -0
- package/dist/{index.js → config.js} +72 -35
- package/dist/edge.js +435 -0
- package/dist/index.d.ts +280 -40
- package/dist/react.cjs +199 -0
- package/dist/react.js +179 -0
- package/dist/server.cjs +500 -0
- package/dist/server.js +452 -0
- package/package.json +38 -13
package/dist/index.d.ts
CHANGED
|
@@ -1,75 +1,315 @@
|
|
|
1
1
|
/// <reference path="../global.d.ts" />
|
|
2
|
-
import {
|
|
2
|
+
import { HawkInitialSettings } from '@hawk.so/browser';
|
|
3
|
+
import { CatcherMessagePayload, EventContext, AffectedUser } from '@hawk.so/types';
|
|
4
|
+
export { AffectedUser, EventContext } from '@hawk.so/types';
|
|
5
|
+
import { BreadcrumbsAPI } from '@hawk.so/core';
|
|
6
|
+
export { BreadcrumbsAPI } from '@hawk.so/core';
|
|
7
|
+
import { Component, ReactNode, ErrorInfo, ReactElement } from 'react';
|
|
3
8
|
|
|
4
9
|
/**
|
|
5
|
-
*
|
|
10
|
+
* Event passed to `beforeSend`: from the browser or from the server
|
|
6
11
|
*/
|
|
7
|
-
|
|
12
|
+
type HawkEvent = CatcherMessagePayload<'errors/javascript'> | CatcherMessagePayload<'errors/nodejs'>;
|
|
13
|
+
/**
|
|
14
|
+
* Options of `init()`. The same options are accepted in the browser and on the server,
|
|
15
|
+
* options of the browser catcher are ignored on the server
|
|
16
|
+
*/
|
|
17
|
+
interface HawkInitOptions extends Pick<HawkInitialSettings, 'user' | 'debug' | 'breadcrumbs' | 'consoleTracking' | 'issues' | 'reconnectionTimeout' | 'transport'> {
|
|
18
|
+
/**
|
|
19
|
+
* Hawk Integration Token. Default is the NEXT_PUBLIC_HAWK_TOKEN environment variable,
|
|
20
|
+
* on the server HAWK_TOKEN is checked first
|
|
21
|
+
*/
|
|
22
|
+
token?: string;
|
|
23
|
+
/**
|
|
24
|
+
* Release id. Default is `process.env.HAWK_RELEASE` set by `withHawkConfig`
|
|
25
|
+
*/
|
|
26
|
+
release?: string;
|
|
8
27
|
/**
|
|
9
|
-
*
|
|
28
|
+
* Collector endpoint overwrite: WebSocket URL in the browser, HTTP URL on the server
|
|
10
29
|
*/
|
|
11
|
-
|
|
30
|
+
collectorEndpoint?: string;
|
|
12
31
|
/**
|
|
13
|
-
*
|
|
32
|
+
* Data sent with every event
|
|
14
33
|
*/
|
|
15
|
-
|
|
34
|
+
context?: EventContext;
|
|
35
|
+
/**
|
|
36
|
+
* Filters or modifies events before sending. Return the event to send it or `false` to drop it
|
|
37
|
+
*/
|
|
38
|
+
beforeSend?: (event: HawkEvent) => HawkEvent | false | void;
|
|
39
|
+
/**
|
|
40
|
+
* Disables catching of uncaught errors and unhandled rejections: `window` handlers in the browser,
|
|
41
|
+
* `process` handlers in Node.js
|
|
42
|
+
*/
|
|
43
|
+
disableGlobalErrorsHandling?: boolean;
|
|
16
44
|
}
|
|
17
45
|
|
|
18
46
|
/**
|
|
19
|
-
*
|
|
47
|
+
* Request passed by Next.js to `onRequestError`
|
|
20
48
|
*/
|
|
21
|
-
interface
|
|
49
|
+
interface RequestErrorRequest {
|
|
22
50
|
/**
|
|
23
|
-
*
|
|
51
|
+
* Request path with the query string
|
|
24
52
|
*/
|
|
25
|
-
|
|
53
|
+
path: string;
|
|
26
54
|
/**
|
|
27
|
-
*
|
|
28
|
-
* Default is HAWK_RELEASE environment variable, commit SHA from CI or git, or the build time
|
|
55
|
+
* HTTP method
|
|
29
56
|
*/
|
|
30
|
-
|
|
57
|
+
method: string;
|
|
31
58
|
/**
|
|
32
|
-
*
|
|
59
|
+
* Request headers
|
|
33
60
|
*/
|
|
34
|
-
|
|
61
|
+
headers: Record<string, string | string[] | undefined>;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Context passed by Next.js to `onRequestError`. Fields differ between Next.js versions, so they are loose strings
|
|
65
|
+
*/
|
|
66
|
+
interface RequestErrorContext {
|
|
35
67
|
/**
|
|
36
|
-
*
|
|
68
|
+
* `App Router` or `Pages Router`
|
|
37
69
|
*/
|
|
38
|
-
|
|
70
|
+
routerKind: string;
|
|
39
71
|
/**
|
|
40
|
-
*
|
|
72
|
+
* Route file path, e.g. `/blog/[slug]`
|
|
41
73
|
*/
|
|
42
|
-
|
|
74
|
+
routePath: string;
|
|
75
|
+
/**
|
|
76
|
+
* `render`, `route`, `action`, `middleware` or `proxy`
|
|
77
|
+
*/
|
|
78
|
+
routeType: string;
|
|
79
|
+
/**
|
|
80
|
+
* Rendering phase of the App Router
|
|
81
|
+
*/
|
|
82
|
+
renderSource?: string;
|
|
83
|
+
/**
|
|
84
|
+
* Revalidation reason: `on-demand` or `stale`
|
|
85
|
+
*/
|
|
86
|
+
revalidateReason?: string;
|
|
87
|
+
/**
|
|
88
|
+
* Render type of the App Router in Next.js 15: `dynamic` or `dynamic-resume`
|
|
89
|
+
*/
|
|
90
|
+
renderType?: string;
|
|
43
91
|
}
|
|
44
92
|
/**
|
|
45
|
-
*
|
|
93
|
+
* Next.js data sent with events in `addons.nextjs`
|
|
46
94
|
*/
|
|
47
|
-
interface
|
|
95
|
+
interface NextjsAddons {
|
|
96
|
+
/**
|
|
97
|
+
* Where the error happened: `nodejs`, `edge` or `browser`
|
|
98
|
+
*/
|
|
99
|
+
runtime?: string;
|
|
100
|
+
/**
|
|
101
|
+
* Error page that caught the error: `error`, `global-error` or `boundary`
|
|
102
|
+
*/
|
|
103
|
+
boundary?: string;
|
|
48
104
|
/**
|
|
49
|
-
*
|
|
105
|
+
* React component stack of the error caught by `HawkErrorBoundary`
|
|
50
106
|
*/
|
|
51
|
-
|
|
107
|
+
componentStack?: string;
|
|
108
|
+
/**
|
|
109
|
+
* Digest of the server error. The same digest is shown on the error page in the browser
|
|
110
|
+
*/
|
|
111
|
+
digest?: string;
|
|
112
|
+
/**
|
|
113
|
+
* `App Router` or `Pages Router`
|
|
114
|
+
*/
|
|
115
|
+
routerKind?: string;
|
|
116
|
+
/**
|
|
117
|
+
* Route file path, e.g. `/blog/[slug]`
|
|
118
|
+
*/
|
|
119
|
+
routePath?: string;
|
|
120
|
+
/**
|
|
121
|
+
* `render`, `route`, `action`, `middleware` or `proxy`
|
|
122
|
+
*/
|
|
123
|
+
routeType?: string;
|
|
124
|
+
/**
|
|
125
|
+
* Rendering phase of the App Router
|
|
126
|
+
*/
|
|
127
|
+
renderSource?: string;
|
|
128
|
+
/**
|
|
129
|
+
* Revalidation reason
|
|
130
|
+
*/
|
|
131
|
+
revalidateReason?: string;
|
|
132
|
+
/**
|
|
133
|
+
* Render type of the App Router
|
|
134
|
+
*/
|
|
135
|
+
renderType?: string;
|
|
136
|
+
/**
|
|
137
|
+
* HTTP method
|
|
138
|
+
*/
|
|
139
|
+
method?: string;
|
|
140
|
+
/**
|
|
141
|
+
* Request path with the query string
|
|
142
|
+
*/
|
|
143
|
+
path?: string;
|
|
144
|
+
/**
|
|
145
|
+
* Request headers that don't contain credentials
|
|
146
|
+
*/
|
|
147
|
+
headers?: Record<string, string>;
|
|
52
148
|
}
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* Sends the error or message to Hawk. Next.js errors of `redirect()` and `notFound()` are skipped
|
|
152
|
+
* @param error - error or message
|
|
153
|
+
* @param context - data sent with the event
|
|
154
|
+
* @param user - user affected by the error, used on the server only. In the browser use `setUser()`
|
|
155
|
+
*/
|
|
156
|
+
declare function send(error: unknown, context?: EventContext, user?: AffectedUser): void;
|
|
157
|
+
/**
|
|
158
|
+
* Sets the user sent with every event in the browser.
|
|
159
|
+
* Ignored on the server: it handles requests of many users at once, so pass the user to `send()` there
|
|
160
|
+
* @param _user - current user
|
|
161
|
+
*/
|
|
162
|
+
declare function setUser(_user: AffectedUser): void;
|
|
163
|
+
/**
|
|
164
|
+
* Removes the user set with `setUser()`. Does nothing on the server
|
|
165
|
+
*/
|
|
166
|
+
declare function clearUser(): void;
|
|
167
|
+
/**
|
|
168
|
+
* Sets data sent with every event. On the server it is shared by all requests of the process
|
|
169
|
+
* @param context - data to send
|
|
170
|
+
*/
|
|
171
|
+
declare function setContext(context: EventContext | undefined): void;
|
|
53
172
|
/**
|
|
54
|
-
*
|
|
173
|
+
* Breadcrumbs sent with the events: actions that happened before the error.
|
|
174
|
+
* Collected in the browser only: on the server requests of different users would be mixed
|
|
55
175
|
*/
|
|
56
|
-
|
|
176
|
+
declare const breadcrumbs: BreadcrumbsAPI;
|
|
57
177
|
/**
|
|
58
|
-
*
|
|
59
|
-
*
|
|
60
|
-
*
|
|
61
|
-
*
|
|
62
|
-
* - after `next build` sends client source maps and recent commits to Hawk and removes the maps
|
|
63
|
-
* @param nextConfig - Next.js config object
|
|
64
|
-
* @param options - Hawk plugin options
|
|
178
|
+
* Waits for the events in progress, e.g. before a serverless function is frozen.
|
|
179
|
+
* `onRequestError` already waits for its events. In the browser resolves at once
|
|
180
|
+
* @param timeout - max time to wait, in milliseconds
|
|
181
|
+
* @returns false when the timeout is reached or the catcher is not created
|
|
65
182
|
*/
|
|
66
|
-
declare function
|
|
183
|
+
declare function flush(timeout?: number): Promise<boolean>;
|
|
184
|
+
/**
|
|
185
|
+
* Sends errors of server components, route handlers, server actions and middleware, on the server only.
|
|
186
|
+
* Export it from `instrumentation.ts`: `export const onRequestError = Hawk.onRequestError`
|
|
187
|
+
* @param error - caught error
|
|
188
|
+
* @param request - failed request
|
|
189
|
+
* @param context - route data
|
|
190
|
+
*/
|
|
191
|
+
declare function onRequestError(error: unknown, request: Readonly<RequestErrorRequest>, context: Readonly<RequestErrorContext>): Promise<void>;
|
|
192
|
+
/**
|
|
193
|
+
* Adds a breadcrumb for every navigation of the App Router, in the browser only.
|
|
194
|
+
* Export it from `instrumentation-client.ts`: `export const onRouterTransitionStart = Hawk.onRouterTransitionStart`
|
|
195
|
+
* @param _url - target URL
|
|
196
|
+
* @param _navigationType - `push`, `replace` or `traverse`
|
|
197
|
+
*/
|
|
198
|
+
declare function onRouterTransitionStart(_url: string, _navigationType: string): void;
|
|
199
|
+
|
|
200
|
+
/**
|
|
201
|
+
* Error passed by Next.js to the error pages
|
|
202
|
+
*/
|
|
203
|
+
type ErrorWithDigest = Error & {
|
|
204
|
+
/**
|
|
205
|
+
* Digest of the server error. Server errors have a generic message in production
|
|
206
|
+
*/
|
|
207
|
+
digest?: string;
|
|
208
|
+
};
|
|
209
|
+
/**
|
|
210
|
+
* Props passed by Next.js to `error.tsx` and `global-error.tsx`
|
|
211
|
+
*/
|
|
212
|
+
interface HawkErrorPageProps {
|
|
213
|
+
/**
|
|
214
|
+
* Caught error
|
|
215
|
+
*/
|
|
216
|
+
error: ErrorWithDigest;
|
|
217
|
+
/**
|
|
218
|
+
* Renders the segment again
|
|
219
|
+
*/
|
|
220
|
+
reset?: () => void;
|
|
221
|
+
}
|
|
222
|
+
/**
|
|
223
|
+
* Props passed to the fallback of `HawkErrorBoundary`
|
|
224
|
+
*/
|
|
225
|
+
interface HawkErrorBoundaryFallbackProps {
|
|
226
|
+
/**
|
|
227
|
+
* Caught error
|
|
228
|
+
*/
|
|
229
|
+
error: unknown;
|
|
230
|
+
/**
|
|
231
|
+
* Renders the children again
|
|
232
|
+
*/
|
|
233
|
+
reset: () => void;
|
|
234
|
+
}
|
|
235
|
+
/**
|
|
236
|
+
* Content, fallback and error callback of `HawkErrorBoundary`
|
|
237
|
+
*/
|
|
238
|
+
interface HawkErrorBoundaryProps {
|
|
239
|
+
/**
|
|
240
|
+
* Content to protect
|
|
241
|
+
*/
|
|
242
|
+
children?: ReactNode;
|
|
243
|
+
/**
|
|
244
|
+
* Shown instead of the children after an error
|
|
245
|
+
*/
|
|
246
|
+
fallback?: ReactNode | ((props: HawkErrorBoundaryFallbackProps) => ReactNode);
|
|
247
|
+
/**
|
|
248
|
+
* Called after the error is sent
|
|
249
|
+
*/
|
|
250
|
+
onError?: (error: unknown, info: ErrorInfo) => void;
|
|
251
|
+
}
|
|
252
|
+
/**
|
|
253
|
+
* Whether `HawkErrorBoundary` shows the fallback, and the error it caught
|
|
254
|
+
*/
|
|
255
|
+
interface HawkErrorBoundaryState {
|
|
256
|
+
/**
|
|
257
|
+
* Whether an error is caught
|
|
258
|
+
*/
|
|
259
|
+
hasError: boolean;
|
|
260
|
+
/**
|
|
261
|
+
* Caught error
|
|
262
|
+
*/
|
|
263
|
+
error: unknown;
|
|
264
|
+
}
|
|
265
|
+
/**
|
|
266
|
+
* Sends the error shown by `error.tsx` to Hawk.
|
|
267
|
+
* Next.js only logs errors caught by error boundaries, so the catcher doesn't get them otherwise
|
|
268
|
+
* @param error - error passed to the error page
|
|
269
|
+
*/
|
|
270
|
+
declare function useHawkError(error: unknown): void;
|
|
271
|
+
/**
|
|
272
|
+
* Ready `app/global-error.tsx`: sends the error and shows a minimal error page.
|
|
273
|
+
* Use it as `export { HawkGlobalError as default } from '@hawk.so/nextjs'`
|
|
274
|
+
* @param props - props passed by Next.js
|
|
275
|
+
*/
|
|
276
|
+
declare function HawkGlobalError({ error, reset }: HawkErrorPageProps): ReactElement;
|
|
277
|
+
/**
|
|
278
|
+
* Error boundary that sends errors of its children to Hawk and shows the fallback.
|
|
279
|
+
* Errors Next.js uses for `redirect()` and `notFound()` are passed to the Next.js boundaries
|
|
280
|
+
*/
|
|
281
|
+
declare class HawkErrorBoundary extends Component<HawkErrorBoundaryProps, HawkErrorBoundaryState> {
|
|
282
|
+
/**
|
|
283
|
+
* Initial state
|
|
284
|
+
*/
|
|
285
|
+
state: HawkErrorBoundaryState;
|
|
286
|
+
/**
|
|
287
|
+
* Shows the fallback after an error
|
|
288
|
+
* @param error - caught error
|
|
289
|
+
*/
|
|
290
|
+
static getDerivedStateFromError(error: unknown): HawkErrorBoundaryState;
|
|
291
|
+
/**
|
|
292
|
+
* Sends the caught error
|
|
293
|
+
* @param error - caught error
|
|
294
|
+
* @param info - component stack
|
|
295
|
+
*/
|
|
296
|
+
componentDidCatch(error: unknown, info: ErrorInfo): void;
|
|
297
|
+
/**
|
|
298
|
+
* Renders the children again
|
|
299
|
+
*/
|
|
300
|
+
reset: () => void;
|
|
301
|
+
/**
|
|
302
|
+
* Renders the children or the fallback
|
|
303
|
+
*/
|
|
304
|
+
render(): ReactNode;
|
|
305
|
+
}
|
|
306
|
+
|
|
67
307
|
/**
|
|
68
|
-
*
|
|
69
|
-
*
|
|
70
|
-
* @param options -
|
|
308
|
+
* Initializes Hawk. Call it in `instrumentation-client.ts` for the browser
|
|
309
|
+
* and in `register()` of `instrumentation.ts` for the server
|
|
310
|
+
* @param options - token, release and other options
|
|
71
311
|
*/
|
|
72
|
-
declare function
|
|
312
|
+
declare function init(options?: HawkInitOptions): void;
|
|
73
313
|
|
|
74
|
-
export {
|
|
75
|
-
export type {
|
|
314
|
+
export { HawkErrorBoundary, HawkGlobalError, breadcrumbs, clearUser, flush, init, onRequestError, onRouterTransitionStart, send, setContext, setUser, useHawkError };
|
|
315
|
+
export type { HawkErrorBoundaryFallbackProps, HawkErrorBoundaryProps, HawkErrorPageProps, HawkEvent, HawkInitOptions, NextjsAddons, RequestErrorContext, RequestErrorRequest };
|
package/dist/react.cjs
ADDED
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
"use client";
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
+
var __export = (target, all) => {
|
|
8
|
+
for (var name in all)
|
|
9
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
10
|
+
};
|
|
11
|
+
var __copyProps = (to, from, except, desc) => {
|
|
12
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
13
|
+
for (let key of __getOwnPropNames(from))
|
|
14
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
15
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
16
|
+
}
|
|
17
|
+
return to;
|
|
18
|
+
};
|
|
19
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
20
|
+
|
|
21
|
+
// src/react/index.tsx
|
|
22
|
+
var react_exports = {};
|
|
23
|
+
__export(react_exports, {
|
|
24
|
+
HawkErrorBoundary: () => HawkErrorBoundary,
|
|
25
|
+
HawkGlobalError: () => HawkGlobalError,
|
|
26
|
+
useHawkError: () => useHawkError
|
|
27
|
+
});
|
|
28
|
+
module.exports = __toCommonJS(react_exports);
|
|
29
|
+
var import_react = require("react");
|
|
30
|
+
|
|
31
|
+
// src/common/carrier.ts
|
|
32
|
+
var CARRIER_KEY = /* @__PURE__ */ Symbol.for("hawk.nextjs");
|
|
33
|
+
function getCarrier() {
|
|
34
|
+
const store = globalThis;
|
|
35
|
+
store[CARRIER_KEY] ??= {};
|
|
36
|
+
return store[CARRIER_KEY];
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// src/common/control-flow.ts
|
|
40
|
+
var CONTROL_FLOW_DIGEST_PREFIXES = [
|
|
41
|
+
"NEXT_REDIRECT",
|
|
42
|
+
"NEXT_HTTP_ERROR_FALLBACK;",
|
|
43
|
+
"NEXT_NOT_FOUND",
|
|
44
|
+
"BAILOUT_TO_CLIENT_SIDE_RENDERING",
|
|
45
|
+
"DYNAMIC_SERVER_USAGE",
|
|
46
|
+
"NEXT_PRERENDER_INTERRUPTED",
|
|
47
|
+
"HANGING_PROMISE_REJECTION"
|
|
48
|
+
];
|
|
49
|
+
var STATIC_GEN_BAILOUT_CODE = "NEXT_STATIC_GEN_BAILOUT";
|
|
50
|
+
var REACT_POSTPONE_TYPE = /* @__PURE__ */ Symbol.for("react.postpone");
|
|
51
|
+
var MAX_CAUSE_DEPTH = 5;
|
|
52
|
+
function isControlFlowDigest(value) {
|
|
53
|
+
return typeof value === "string" && CONTROL_FLOW_DIGEST_PREFIXES.some((prefix) => value.startsWith(prefix));
|
|
54
|
+
}
|
|
55
|
+
function isNextControlFlowError(error) {
|
|
56
|
+
let current = error;
|
|
57
|
+
for (let depth = 0; depth < MAX_CAUSE_DEPTH; depth++) {
|
|
58
|
+
if (typeof current !== "object" || current === null) {
|
|
59
|
+
return false;
|
|
60
|
+
}
|
|
61
|
+
const value = current;
|
|
62
|
+
if (isControlFlowDigest(value.digest) || isControlFlowDigest(value.message) || value.code === STATIC_GEN_BAILOUT_CODE || value.$$typeof === REACT_POSTPONE_TYPE) {
|
|
63
|
+
return true;
|
|
64
|
+
}
|
|
65
|
+
current = value.cause;
|
|
66
|
+
}
|
|
67
|
+
return false;
|
|
68
|
+
}
|
|
69
|
+
function getDigest(error) {
|
|
70
|
+
if (typeof error === "object" && error !== null) {
|
|
71
|
+
const { digest } = error;
|
|
72
|
+
if (typeof digest === "string" && digest !== "") {
|
|
73
|
+
return digest;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
return void 0;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// src/react/index.tsx
|
|
80
|
+
var import_jsx_runtime = require("react/jsx-runtime");
|
|
81
|
+
function captureBoundaryError(error, boundary, componentStack) {
|
|
82
|
+
if (isNextControlFlowError(error) || getDigest(error) !== void 0) {
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
getCarrier().capture?.(error, {
|
|
86
|
+
boundary,
|
|
87
|
+
...typeof componentStack === "string" ? { componentStack } : {}
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
function useHawkError(error) {
|
|
91
|
+
(0, import_react.useEffect)(() => {
|
|
92
|
+
captureBoundaryError(error, "error");
|
|
93
|
+
}, [error]);
|
|
94
|
+
}
|
|
95
|
+
var globalErrorStyles = {
|
|
96
|
+
container: {
|
|
97
|
+
fontFamily: "system-ui, sans-serif",
|
|
98
|
+
minHeight: "100vh",
|
|
99
|
+
display: "flex",
|
|
100
|
+
flexDirection: "column",
|
|
101
|
+
alignItems: "center",
|
|
102
|
+
justifyContent: "center",
|
|
103
|
+
gap: 16,
|
|
104
|
+
textAlign: "center"
|
|
105
|
+
},
|
|
106
|
+
title: {
|
|
107
|
+
fontSize: 14,
|
|
108
|
+
fontWeight: 400,
|
|
109
|
+
margin: 0
|
|
110
|
+
},
|
|
111
|
+
digest: {
|
|
112
|
+
fontSize: 12,
|
|
113
|
+
opacity: 0.6,
|
|
114
|
+
margin: 0
|
|
115
|
+
},
|
|
116
|
+
button: {
|
|
117
|
+
fontSize: 14,
|
|
118
|
+
padding: "6px 14px",
|
|
119
|
+
cursor: "pointer"
|
|
120
|
+
}
|
|
121
|
+
};
|
|
122
|
+
function HawkGlobalError({ error, reset }) {
|
|
123
|
+
(0, import_react.useEffect)(() => {
|
|
124
|
+
captureBoundaryError(error, "global-error");
|
|
125
|
+
}, [error]);
|
|
126
|
+
const side = error.digest === void 0 ? "client" : "server";
|
|
127
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("html", { lang: "en", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("body", { children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("main", { style: globalErrorStyles.container, children: [
|
|
128
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("h2", { style: globalErrorStyles.title, children: [
|
|
129
|
+
"Application error: a ",
|
|
130
|
+
side,
|
|
131
|
+
"-side exception has occurred."
|
|
132
|
+
] }),
|
|
133
|
+
error.digest !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", { style: globalErrorStyles.digest, children: [
|
|
134
|
+
"Digest: ",
|
|
135
|
+
error.digest
|
|
136
|
+
] }),
|
|
137
|
+
reset !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { type: "button", style: globalErrorStyles.button, onClick: reset, children: "Try again" })
|
|
138
|
+
] }) }) });
|
|
139
|
+
}
|
|
140
|
+
var HawkErrorBoundary = class extends import_react.Component {
|
|
141
|
+
/**
|
|
142
|
+
* Initial state
|
|
143
|
+
*/
|
|
144
|
+
state = {
|
|
145
|
+
hasError: false,
|
|
146
|
+
error: null
|
|
147
|
+
};
|
|
148
|
+
/**
|
|
149
|
+
* Shows the fallback after an error
|
|
150
|
+
* @param error - caught error
|
|
151
|
+
*/
|
|
152
|
+
static getDerivedStateFromError(error) {
|
|
153
|
+
return {
|
|
154
|
+
hasError: true,
|
|
155
|
+
error
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Sends the caught error
|
|
160
|
+
* @param error - caught error
|
|
161
|
+
* @param info - component stack
|
|
162
|
+
*/
|
|
163
|
+
componentDidCatch(error, info) {
|
|
164
|
+
if (isNextControlFlowError(error)) {
|
|
165
|
+
return;
|
|
166
|
+
}
|
|
167
|
+
captureBoundaryError(error, "boundary", info.componentStack);
|
|
168
|
+
this.props.onError?.(error, info);
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Renders the children again
|
|
172
|
+
*/
|
|
173
|
+
reset = () => {
|
|
174
|
+
this.setState({
|
|
175
|
+
hasError: false,
|
|
176
|
+
error: null
|
|
177
|
+
});
|
|
178
|
+
};
|
|
179
|
+
/**
|
|
180
|
+
* Renders the children or the fallback
|
|
181
|
+
*/
|
|
182
|
+
render() {
|
|
183
|
+
const { hasError, error } = this.state;
|
|
184
|
+
if (!hasError) {
|
|
185
|
+
return this.props.children;
|
|
186
|
+
}
|
|
187
|
+
if (isNextControlFlowError(error)) {
|
|
188
|
+
throw error;
|
|
189
|
+
}
|
|
190
|
+
const { fallback } = this.props;
|
|
191
|
+
if (typeof fallback === "function") {
|
|
192
|
+
return fallback({
|
|
193
|
+
error,
|
|
194
|
+
reset: this.reset
|
|
195
|
+
});
|
|
196
|
+
}
|
|
197
|
+
return fallback ?? null;
|
|
198
|
+
}
|
|
199
|
+
};
|