@belvador/cloudflare 0.4.0 → 0.4.1
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/dist/index.d.ts +2 -0
- package/dist/index.js +50 -4
- package/package.json +2 -2
package/dist/index.d.ts
CHANGED
|
@@ -19,6 +19,8 @@ export type BelvadorEnv = {
|
|
|
19
19
|
};
|
|
20
20
|
/** Engine options for one Worker invocation (exported for tests and @belvador/tanstack-start). */
|
|
21
21
|
export declare function workerEngineOptions(options: WorkerOptions | undefined, env: unknown, runtime?: "cloudflare" | "tanstack-start"): EngineCloudflareOptions;
|
|
22
|
+
/** Mechanism of an error from a rejected `ctx.waitUntil` promise (unhandled: nothing caught it). */
|
|
23
|
+
export declare const WAIT_UNTIL_MECHANISM = "auto.faas.cloudflare.wait_until";
|
|
22
24
|
/** Shared with @belvador/tanstack-start so its server events carry its own SDK name. */
|
|
23
25
|
export declare function wrapHandler<Env, H>(optionsCallback: (env: Env) => WorkerOptions | undefined, handler: H, runtime: "cloudflare" | "tanstack-start"): H;
|
|
24
26
|
/**
|
package/dist/index.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// Built on the open-source Sentry JavaScript SDK (MIT), with Belvador's
|
|
3
3
|
// privacy and sending rules. Needs the `nodejs_compat` (or `nodejs_als`)
|
|
4
4
|
// compatibility flag so every request gets its own scope.
|
|
5
|
-
import { consoleIntegration, dedupeIntegration, eventFiltersIntegration, fetchIntegration, linkedErrorsIntegration, requestDataIntegration, withSentry, } from "@sentry/cloudflare";
|
|
5
|
+
import { captureException, consoleIntegration, dedupeIntegration, eventFiltersIntegration, fetchIntegration, linkedErrorsIntegration, requestDataIntegration, withSentry, } from "@sentry/cloudflare";
|
|
6
6
|
import { OTEL_OPTION, TRACE_OPTION, buildEngineOptions, otelBridgeIntegration, currentHooks, installTracePropagation, markHooked, noteClientAbort, runVerification, withIncomingTraceparent, } from "@belvador/core";
|
|
7
7
|
export { SDK_VERSION, addBreadcrumb, captureCheckIn, captureException, captureMessage, close, flush, heartbeat, withMonitor, getDiagnostics, lastEventId, setContext, setTag, setTags, setUser, withScope, } from "@belvador/core";
|
|
8
8
|
function binding(env, name) {
|
|
@@ -96,10 +96,55 @@ export function workerEngineOptions(options, env, runtime = "cloudflare") {
|
|
|
96
96
|
}
|
|
97
97
|
}
|
|
98
98
|
const HANDLER_METHODS = ["fetch", "scheduled", "queue", "email", "tail"];
|
|
99
|
+
/** Every module handler receives `(input, env, ctx)`; ctx is the ExecutionContext. */
|
|
100
|
+
const CTX_ARG = 2;
|
|
101
|
+
/** Mechanism of an error from a rejected `ctx.waitUntil` promise (unhandled: nothing caught it). */
|
|
102
|
+
export const WAIT_UNTIL_MECHANISM = "auto.faas.cloudflare.wait_until";
|
|
103
|
+
/**
|
|
104
|
+
* The handler's own view of ctx: `waitUntil` reports a rejected promise as an unhandled
|
|
105
|
+
* error, then hands the runtime the same rejection, so Cloudflare still logs it and the
|
|
106
|
+
* promise keeps its meaning. Everything else is the real ctx. The engine keeps the
|
|
107
|
+
* original object, so its own flush is untouched; it waits (up to its 2 s flush timeout)
|
|
108
|
+
* for promises passed here, which is what lets a late rejection still be sent.
|
|
109
|
+
*/
|
|
110
|
+
function reportingContext(ctx) {
|
|
111
|
+
if (ctx === null || typeof ctx !== "object")
|
|
112
|
+
return ctx;
|
|
113
|
+
try {
|
|
114
|
+
if (typeof ctx.waitUntil !== "function")
|
|
115
|
+
return ctx;
|
|
116
|
+
}
|
|
117
|
+
catch {
|
|
118
|
+
return ctx;
|
|
119
|
+
}
|
|
120
|
+
const waitUntil = (promise) => {
|
|
121
|
+
const real = Reflect.get(ctx, "waitUntil", ctx);
|
|
122
|
+
if (!isThenable(promise))
|
|
123
|
+
return real.call(ctx, promise);
|
|
124
|
+
return real.call(ctx, Promise.resolve(promise).then(undefined, (error) => {
|
|
125
|
+
try {
|
|
126
|
+
captureException(error, { mechanism: { type: WAIT_UNTIL_MECHANISM, handled: false } });
|
|
127
|
+
}
|
|
128
|
+
catch {
|
|
129
|
+
/* reporting must never change the app's behaviour */
|
|
130
|
+
}
|
|
131
|
+
throw error;
|
|
132
|
+
}));
|
|
133
|
+
};
|
|
134
|
+
return new Proxy(ctx, {
|
|
135
|
+
get(target, prop) {
|
|
136
|
+
if (prop === "waitUntil")
|
|
137
|
+
return waitUntil;
|
|
138
|
+
const value = Reflect.get(target, prop, target);
|
|
139
|
+
return typeof value === "function" ? value.bind(target) : value;
|
|
140
|
+
},
|
|
141
|
+
});
|
|
142
|
+
}
|
|
99
143
|
/**
|
|
100
144
|
* Marks each invocation of an object handler as running inside the wrapper (integration
|
|
101
|
-
* health: `verifyIntegration` can tell),
|
|
102
|
-
* disconnected so the error counts as a cancellation.
|
|
145
|
+
* health: `verifyIntegration` can tell), reports rejected `ctx.waitUntil` promises, and notes
|
|
146
|
+
* a fetch that failed after its client disconnected so the error counts as a cancellation.
|
|
147
|
+
* Class handlers pass through unchanged.
|
|
103
148
|
*/
|
|
104
149
|
function marked(handler) {
|
|
105
150
|
if (handler === null || typeof handler !== "object")
|
|
@@ -109,8 +154,9 @@ function marked(handler) {
|
|
|
109
154
|
const fn = handler[name];
|
|
110
155
|
if (typeof fn !== "function")
|
|
111
156
|
continue;
|
|
112
|
-
out[name] = function (...
|
|
157
|
+
out[name] = function (...input) {
|
|
113
158
|
markHooked("wrapper");
|
|
159
|
+
const args = input.length > CTX_ARG ? input.map((a, i) => (i === CTX_ARG ? reportingContext(a) : a)) : input;
|
|
114
160
|
const signal = name === "fetch" ? signalOf(args[0]) : undefined;
|
|
115
161
|
if (!signal)
|
|
116
162
|
return fn.apply(handler, args);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@belvador/cloudflare",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.1",
|
|
4
4
|
"description": "Belvador error tracking for Cloudflare Workers: per-request scope, errors only, private by default.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Belvador (https://belvador.dev)",
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
"node": ">=18"
|
|
33
33
|
},
|
|
34
34
|
"dependencies": {
|
|
35
|
-
"@belvador/core": "0.4.
|
|
35
|
+
"@belvador/core": "0.4.1",
|
|
36
36
|
"@sentry/cloudflare": "10.76.2"
|
|
37
37
|
},
|
|
38
38
|
"publishConfig": {
|