veryfront 0.1.1162 → 0.1.1165
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/esm/cli/commands/serve/command.d.ts.map +1 -1
- package/esm/cli/commands/serve/command.js +4 -0
- package/esm/deno.d.ts +2 -0
- package/esm/deno.js +4 -1
- package/esm/src/observability/application-errors.d.ts +16 -0
- package/esm/src/observability/application-errors.d.ts.map +1 -0
- package/esm/src/observability/application-errors.js +15 -0
- package/esm/src/observability/sentry.d.ts +19 -0
- package/esm/src/observability/sentry.d.ts.map +1 -0
- package/esm/src/observability/sentry.js +48 -0
- package/esm/src/proxy/main.js +14 -1
- package/esm/src/server/production-server.js +10 -0
- package/esm/src/server/runtime-handler/index.d.ts.map +1 -1
- package/esm/src/server/runtime-handler/index.js +10 -1
- package/esm/src/server/runtime-handler/tracing.d.ts +4 -0
- package/esm/src/server/runtime-handler/tracing.d.ts.map +1 -1
- package/esm/src/server/runtime-handler/tracing.js +8 -0
- package/esm/src/server/services/rendering/ssr.service.d.ts.map +1 -1
- package/esm/src/server/services/rendering/ssr.service.js +10 -1
- package/esm/src/utils/version-constant.d.ts +1 -1
- package/esm/src/utils/version-constant.js +1 -1
- package/package.json +9 -5
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"command.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/serve/command.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,UAAU,GAAG,OAAO,GAAG,YAAY,CAAC;IAC1C,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,OAAO,CAAC;IACnB,SAAS,EAAE,OAAO,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,OAAO,CAAC;CAChB;
|
|
1
|
+
{"version":3,"file":"command.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/serve/command.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,UAAU,GAAG,OAAO,GAAG,YAAY,CAAC;IAC1C,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,OAAO,CAAC;IACnB,SAAS,EAAE,OAAO,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,OAAO,CAAC;CAChB;AAwGD,wBAAsB,YAAY,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAcvE"}
|
|
@@ -30,6 +30,8 @@ async function runProxy(options) {
|
|
|
30
30
|
}
|
|
31
31
|
async function runProductionServer(options) {
|
|
32
32
|
showLogo();
|
|
33
|
+
const { captureApplicationError, flushApplicationErrors, initializeSentryFromEnv, } = await import("../../../src/observability/sentry.js");
|
|
34
|
+
await initializeSentryFromEnv();
|
|
33
35
|
const { clearAllLocalCaches } = await import("../../../src/transforms/mdx/esm-module-loader/cache/index.js");
|
|
34
36
|
await clearAllLocalCaches();
|
|
35
37
|
const { initializeOTLPWithApis } = await import("../../../src/observability/tracing/otlp-setup.js");
|
|
@@ -66,9 +68,11 @@ async function runProductionServer(options) {
|
|
|
66
68
|
});
|
|
67
69
|
}
|
|
68
70
|
catch (error) {
|
|
71
|
+
captureApplicationError(error, { boundary: "process.shutdown" });
|
|
69
72
|
cliLogger.warn("Error while shutting down production server:", error);
|
|
70
73
|
}
|
|
71
74
|
finally {
|
|
75
|
+
await flushApplicationErrors();
|
|
72
76
|
exitProcess(0);
|
|
73
77
|
}
|
|
74
78
|
};
|
package/esm/deno.d.ts
CHANGED
|
@@ -51,6 +51,7 @@ declare namespace _default {
|
|
|
51
51
|
"./mcp": string;
|
|
52
52
|
"./middleware": string;
|
|
53
53
|
"./observability": string;
|
|
54
|
+
"./observability/sentry": string;
|
|
54
55
|
"./observability/otlp-setup": string;
|
|
55
56
|
"./utils": string;
|
|
56
57
|
"./oauth": string;
|
|
@@ -138,6 +139,7 @@ declare namespace _default {
|
|
|
138
139
|
"veryfront/proxy/cache": string;
|
|
139
140
|
"veryfront/transforms/mdx-cache": string;
|
|
140
141
|
"veryfront/observability/otlp-setup": string;
|
|
142
|
+
"veryfront/observability/sentry": string;
|
|
141
143
|
"veryfront/platform/esbuild-init": string;
|
|
142
144
|
"veryfront/platform/path": string;
|
|
143
145
|
"veryfront/platform/http": string;
|
package/esm/deno.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export default {
|
|
2
2
|
"name": "veryfront",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.1165",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"nodeModulesDir": "auto",
|
|
6
6
|
"minimumDependencyAge": {
|
|
@@ -52,6 +52,7 @@ export default {
|
|
|
52
52
|
"./extensions/ext-parser-babel",
|
|
53
53
|
"./extensions/ext-sandbox-shell-tools",
|
|
54
54
|
"./extensions/ext-observability-opentelemetry",
|
|
55
|
+
"./extensions/ext-observability-sentry",
|
|
55
56
|
"./extensions/ext-eval-report-mlflow",
|
|
56
57
|
"./extensions/ext-eval-report-http",
|
|
57
58
|
"./extensions/ext-content-mdx",
|
|
@@ -111,6 +112,7 @@ export default {
|
|
|
111
112
|
"./mcp": "./src/mcp/index.ts",
|
|
112
113
|
"./middleware": "./src/middleware/index.ts",
|
|
113
114
|
"./observability": "./src/observability/index.ts",
|
|
115
|
+
"./observability/sentry": "./src/observability/sentry.ts",
|
|
114
116
|
"./observability/otlp-setup": "./src/observability/tracing/otlp-setup.ts",
|
|
115
117
|
"./utils": "./src/utils/index.ts",
|
|
116
118
|
"./oauth": "./src/oauth/index.ts",
|
|
@@ -198,6 +200,7 @@ export default {
|
|
|
198
200
|
"veryfront/proxy/cache": "./src/proxy/cache/index.ts",
|
|
199
201
|
"veryfront/transforms/mdx-cache": "./src/transforms/mdx/esm-module-loader/cache/index.ts",
|
|
200
202
|
"veryfront/observability/otlp-setup": "./src/observability/tracing/otlp-setup.ts",
|
|
203
|
+
"veryfront/observability/sentry": "./src/observability/sentry.ts",
|
|
201
204
|
"veryfront/platform/esbuild-init": "./src/platform/compat/esbuild-init.ts",
|
|
202
205
|
"veryfront/platform/path": "./src/platform/compat/path/index.ts",
|
|
203
206
|
"veryfront/platform/http": "./src/platform/compat/http/index.ts",
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export type ApplicationErrorContext = {
|
|
2
|
+
boundary: string;
|
|
3
|
+
method?: string;
|
|
4
|
+
requestId?: string;
|
|
5
|
+
spanId?: string;
|
|
6
|
+
traceId?: string;
|
|
7
|
+
};
|
|
8
|
+
export type ApplicationErrorReporter = {
|
|
9
|
+
capture(error: unknown, context: ApplicationErrorContext): string | undefined;
|
|
10
|
+
flush(timeoutMs?: number): Promise<boolean>;
|
|
11
|
+
};
|
|
12
|
+
export declare function setApplicationErrorReporter(nextReporter: ApplicationErrorReporter | undefined): void;
|
|
13
|
+
export declare function captureApplicationError(error: unknown, context: ApplicationErrorContext): string | undefined;
|
|
14
|
+
export declare function flushApplicationErrors(timeoutMs?: number): Promise<boolean>;
|
|
15
|
+
export declare function isExpectedApplicationError(error: unknown): boolean;
|
|
16
|
+
//# sourceMappingURL=application-errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"application-errors.d.ts","sourceRoot":"","sources":["../../../src/src/observability/application-errors.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,uBAAuB,GAAG;IACpC,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,wBAAwB,GAAG;IACrC,OAAO,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,uBAAuB,GAAG,MAAM,GAAG,SAAS,CAAC;IAC9E,KAAK,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CAC7C,CAAC;AAIF,wBAAgB,2BAA2B,CACzC,YAAY,EAAE,wBAAwB,GAAG,SAAS,GACjD,IAAI,CAEN;AAED,wBAAgB,uBAAuB,CACrC,KAAK,EAAE,OAAO,EACd,OAAO,EAAE,uBAAuB,GAC/B,MAAM,GAAG,SAAS,CAGpB;AAED,wBAAgB,sBAAsB,CAAC,SAAS,SAAQ,GAAG,OAAO,CAAC,OAAO,CAAC,CAE1E;AAED,wBAAgB,0BAA0B,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAElE"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
let reporter;
|
|
2
|
+
export function setApplicationErrorReporter(nextReporter) {
|
|
3
|
+
reporter = nextReporter;
|
|
4
|
+
}
|
|
5
|
+
export function captureApplicationError(error, context) {
|
|
6
|
+
if (isExpectedApplicationError(error))
|
|
7
|
+
return undefined;
|
|
8
|
+
return reporter?.capture(error, context);
|
|
9
|
+
}
|
|
10
|
+
export function flushApplicationErrors(timeoutMs = 2_000) {
|
|
11
|
+
return reporter?.flush(timeoutMs) ?? Promise.resolve(true);
|
|
12
|
+
}
|
|
13
|
+
export function isExpectedApplicationError(error) {
|
|
14
|
+
return error instanceof DOMException && error.name === "AbortError";
|
|
15
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import "../../_dnt.polyfills.js";
|
|
2
|
+
import { type ApplicationErrorReporter, captureApplicationError, flushApplicationErrors } from "./application-errors.js";
|
|
3
|
+
export { captureApplicationError, flushApplicationErrors };
|
|
4
|
+
export type { ApplicationErrorContext, ApplicationErrorReporter } from "./application-errors.js";
|
|
5
|
+
export type SentryConfig = {
|
|
6
|
+
dsn?: string;
|
|
7
|
+
environment?: string;
|
|
8
|
+
release?: string;
|
|
9
|
+
serviceName?: string;
|
|
10
|
+
};
|
|
11
|
+
type SentryExtensionModule = {
|
|
12
|
+
createSentryApplicationErrorReporter(config: Required<SentryConfig>): ApplicationErrorReporter;
|
|
13
|
+
};
|
|
14
|
+
type SentryExtensionLoader = () => Promise<SentryExtensionModule>;
|
|
15
|
+
export declare function resolveSentryConfigFromEnv(defaultServiceName?: string): SentryConfig | undefined;
|
|
16
|
+
export declare function initializeSentryFromEnv(defaultServiceName?: string): Promise<boolean>;
|
|
17
|
+
export declare function initializeSentry(config: SentryConfig, loadExtension?: SentryExtensionLoader): Promise<boolean>;
|
|
18
|
+
export declare function resetSentryForTests(): void;
|
|
19
|
+
//# sourceMappingURL=sentry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sentry.d.ts","sourceRoot":"","sources":["../../../src/src/observability/sentry.ts"],"names":[],"mappings":"AAAA,OAAO,yBAAyB,CAAC;AAGjC,OAAO,EACL,KAAK,wBAAwB,EAC7B,uBAAuB,EACvB,sBAAsB,EAEvB,MAAM,yBAAyB,CAAC;AAEjC,OAAO,EAAE,uBAAuB,EAAE,sBAAsB,EAAE,CAAC;AAC3D,YAAY,EAAE,uBAAuB,EAAE,wBAAwB,EAAE,MAAM,yBAAyB,CAAC;AAKjG,MAAM,MAAM,YAAY,GAAG;IACzB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF,KAAK,qBAAqB,GAAG;IAC3B,oCAAoC,CAAC,MAAM,EAAE,QAAQ,CAAC,YAAY,CAAC,GAAG,wBAAwB,CAAC;CAChG,CAAC;AAEF,KAAK,qBAAqB,GAAG,MAAM,OAAO,CAAC,qBAAqB,CAAC,CAAC;AAIlE,wBAAgB,0BAA0B,CACxC,kBAAkB,SAAuB,GACxC,YAAY,GAAG,SAAS,CAY1B;AAED,wBAAgB,uBAAuB,CACrC,kBAAkB,SAAuB,GACxC,OAAO,CAAC,OAAO,CAAC,CAGlB;AAED,wBAAsB,gBAAgB,CACpC,MAAM,EAAE,YAAY,EACpB,aAAa,GAAE,qBAA2C,GACzD,OAAO,CAAC,OAAO,CAAC,CAgBlB;AAED,wBAAgB,mBAAmB,IAAI,IAAI,CAG1C"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import "../../_dnt.polyfills.js";
|
|
2
|
+
import { importFirstPartyExtensionModule } from "../extensions/first-party-import.js";
|
|
3
|
+
import { getEnv } from "../platform/compat/process.js";
|
|
4
|
+
import { captureApplicationError, flushApplicationErrors, setApplicationErrorReporter, } from "./application-errors.js";
|
|
5
|
+
export { captureApplicationError, flushApplicationErrors };
|
|
6
|
+
const DEFAULT_SERVICE_NAME = "veryfront-server";
|
|
7
|
+
const SENTRY_ERROR_REPORTER = "sentry";
|
|
8
|
+
let initialized = false;
|
|
9
|
+
export function resolveSentryConfigFromEnv(defaultServiceName = DEFAULT_SERVICE_NAME) {
|
|
10
|
+
if (getEnv("VERYFRONT_ERROR_REPORTER")?.trim().toLowerCase() !== SENTRY_ERROR_REPORTER) {
|
|
11
|
+
return undefined;
|
|
12
|
+
}
|
|
13
|
+
return {
|
|
14
|
+
dsn: getEnv("SENTRY_DSN"),
|
|
15
|
+
environment: getEnv("SENTRY_ENVIRONMENT") ?? getEnv("OTEL_DEPLOYMENT_ENVIRONMENT"),
|
|
16
|
+
release: getEnv("SENTRY_RELEASE") ?? getEnv("OTEL_SERVICE_VERSION"),
|
|
17
|
+
serviceName: (getEnv("SENTRY_SERVICE_NAME") ?? getEnv("OTEL_SERVICE_NAME"))?.trim() ||
|
|
18
|
+
defaultServiceName,
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
export function initializeSentryFromEnv(defaultServiceName = DEFAULT_SERVICE_NAME) {
|
|
22
|
+
const config = resolveSentryConfigFromEnv(defaultServiceName);
|
|
23
|
+
return config ? initializeSentry(config) : Promise.resolve(false);
|
|
24
|
+
}
|
|
25
|
+
export async function initializeSentry(config, loadExtension = loadSentryExtension) {
|
|
26
|
+
if (initialized)
|
|
27
|
+
return true;
|
|
28
|
+
const dsn = config.dsn?.trim();
|
|
29
|
+
if (!dsn)
|
|
30
|
+
return false;
|
|
31
|
+
const extension = await loadExtension();
|
|
32
|
+
const reporter = extension.createSentryApplicationErrorReporter({
|
|
33
|
+
dsn,
|
|
34
|
+
environment: config.environment?.trim() ?? "",
|
|
35
|
+
release: config.release?.trim() ?? "",
|
|
36
|
+
serviceName: config.serviceName?.trim() || DEFAULT_SERVICE_NAME,
|
|
37
|
+
});
|
|
38
|
+
setApplicationErrorReporter(reporter);
|
|
39
|
+
initialized = true;
|
|
40
|
+
return true;
|
|
41
|
+
}
|
|
42
|
+
export function resetSentryForTests() {
|
|
43
|
+
initialized = false;
|
|
44
|
+
setApplicationErrorReporter(undefined);
|
|
45
|
+
}
|
|
46
|
+
function loadSentryExtension() {
|
|
47
|
+
return importFirstPartyExtensionModule("ext-observability-sentry", "@veryfront/ext-observability-sentry");
|
|
48
|
+
}
|
package/esm/src/proxy/main.js
CHANGED
|
@@ -47,6 +47,10 @@ import { removeStickyCookieFromPublicCacheableResponse } from "./response-header
|
|
|
47
47
|
import { closeProxyServerWithin, createProxyDrainingResponse, parseProxyDrainTimeoutMs, ProxyRequestDrainTracker, } from "./request-drain.js";
|
|
48
48
|
import { handleProxyRoutingInvalidationRequest, PROXY_ROUTING_INVALIDATION_PATH, } from "./routing-invalidation.js";
|
|
49
49
|
import { startProxyRoutingInvalidationBus } from "./routing-invalidation-redis.js";
|
|
50
|
+
import { captureApplicationError, flushApplicationErrors, } from "../observability/application-errors.js";
|
|
51
|
+
import { initializeSentryFromEnv } from "../observability/sentry.js";
|
|
52
|
+
import { getTraceContext } from "./tracing.js";
|
|
53
|
+
await initializeSentryFromEnv("veryfront-proxy");
|
|
50
54
|
function getLocalProjects() {
|
|
51
55
|
const raw = getEnv("LOCAL_PROJECTS");
|
|
52
56
|
return raw ? JSON.parse(raw) : {};
|
|
@@ -449,6 +453,11 @@ function forwardToServer(req, url) {
|
|
|
449
453
|
}
|
|
450
454
|
catch (error) {
|
|
451
455
|
const ms = Math.round(performance.now() - startTime);
|
|
456
|
+
captureApplicationError(error, {
|
|
457
|
+
boundary: "proxy.request",
|
|
458
|
+
method: req.method,
|
|
459
|
+
...getTraceContext(),
|
|
460
|
+
});
|
|
452
461
|
proxyLogger.error(`500 ${req.method} ${url.pathname}`, { ms }, error);
|
|
453
462
|
lifecycle.end(500, error);
|
|
454
463
|
return withProxyTiming(jsonErrorResponse(500, {
|
|
@@ -604,10 +613,13 @@ async function shutdown(signal) {
|
|
|
604
613
|
serverResolver.close();
|
|
605
614
|
await proxyHandler.close();
|
|
606
615
|
await shutdownOTLP();
|
|
616
|
+
await flushApplicationErrors();
|
|
607
617
|
proxyLogger.info("Closed connections");
|
|
608
618
|
}
|
|
609
619
|
catch (error) {
|
|
620
|
+
captureApplicationError(error, { boundary: "process.shutdown" });
|
|
610
621
|
proxyLogger.error("Error while shutting down proxy", error);
|
|
622
|
+
await flushApplicationErrors();
|
|
611
623
|
}
|
|
612
624
|
finally {
|
|
613
625
|
exit(0);
|
|
@@ -615,8 +627,9 @@ async function shutdown(signal) {
|
|
|
615
627
|
}
|
|
616
628
|
const handleSignal = (signal) => {
|
|
617
629
|
void shutdown(signal).catch((error) => {
|
|
630
|
+
captureApplicationError(error, { boundary: "process.shutdown" });
|
|
618
631
|
proxyLogger.error("Unhandled shutdown error", { signal }, error);
|
|
619
|
-
exit(1);
|
|
632
|
+
void flushApplicationErrors().finally(() => exit(1));
|
|
620
633
|
});
|
|
621
634
|
};
|
|
622
635
|
onSignal("SIGINT", () => handleSignal("SIGINT"));
|
|
@@ -193,6 +193,9 @@ export function startProductionServer(options) {
|
|
|
193
193
|
}, { "server.port": options.port, "server.bindAddress": options.bindAddress ?? "0.0.0.0" });
|
|
194
194
|
}
|
|
195
195
|
if (globalThis[Symbol.for("import-meta-ponyfill-esmodule")](import.meta).main) {
|
|
196
|
+
const { captureApplicationError, flushApplicationErrors, } = await import("../observability/application-errors.js");
|
|
197
|
+
const { initializeSentryFromEnv } = await import("../observability/sentry.js");
|
|
198
|
+
await initializeSentryFromEnv();
|
|
196
199
|
// Register global error handlers FIRST to prevent process crashes from application errors
|
|
197
200
|
// This ensures the renderer stays up even if user code throws unhandled exceptions
|
|
198
201
|
onGlobalError((error, type) => {
|
|
@@ -208,6 +211,9 @@ if (globalThis[Symbol.for("import-meta-ponyfill-esmodule")](import.meta).main) {
|
|
|
208
211
|
const isOOM = error.message.includes("out of memory") ||
|
|
209
212
|
error.message.includes("allocation failed");
|
|
210
213
|
const isFatal = isStackOverflow || isOOM;
|
|
214
|
+
captureApplicationError(error, {
|
|
215
|
+
boundary: `process.${type}`,
|
|
216
|
+
});
|
|
211
217
|
globalLog.error(`${type}: Application error caught`, {
|
|
212
218
|
message: error.message,
|
|
213
219
|
stack: error.stack,
|
|
@@ -277,9 +283,11 @@ if (globalThis[Symbol.for("import-meta-ponyfill-esmodule")](import.meta).main) {
|
|
|
277
283
|
stop: server.stop,
|
|
278
284
|
logger,
|
|
279
285
|
});
|
|
286
|
+
await flushApplicationErrors();
|
|
280
287
|
};
|
|
281
288
|
const handleSignal = (signal) => {
|
|
282
289
|
void shutdown(signal).catch((error) => {
|
|
290
|
+
captureApplicationError(error, { boundary: "process.shutdown" });
|
|
283
291
|
logger.warn("Unhandled error while shutting down production server", { signal, error });
|
|
284
292
|
});
|
|
285
293
|
};
|
|
@@ -287,7 +295,9 @@ if (globalThis[Symbol.for("import-meta-ponyfill-esmodule")](import.meta).main) {
|
|
|
287
295
|
onSignal("SIGTERM", () => handleSignal("SIGTERM"));
|
|
288
296
|
}
|
|
289
297
|
catch (e) {
|
|
298
|
+
captureApplicationError(e, { boundary: "process.startup" });
|
|
290
299
|
logger.error("Failed to start production server:", e);
|
|
300
|
+
await flushApplicationErrors();
|
|
291
301
|
// Re-throw so the process exits with a non-zero code. A running process with no HTTP
|
|
292
302
|
// listener causes K8s readiness probes to fail eventually, but crashing immediately
|
|
293
303
|
// signals the orchestrator to restart the pod faster.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/src/server/runtime-handler/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AACtE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAG7D,OAAO,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAC;AAChE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/src/server/runtime-handler/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AACtE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAG7D,OAAO,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAC;AAChE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAmCpD,OAAO,EAAE,iBAAiB,EAAE,MAAM,kCAAkC,CAAC;AAwErE,OAAO,EAAE,qBAAqB,EAAE,KAAK,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAMtF,2CAA2C;AAC3C,eAAO,MAAM,aAAa,4vBAqChB,CAAC;AAEX,6CAA6C;AAC7C,MAAM,MAAM,WAAW,GAAG,CAAC,OAAO,aAAa,CAAC,CAAC,MAAM,CAAC,CAAC;AAEzD;;;;GAIG;AACH,MAAM,WAAW,mBAAmB;IAClC,8CAA8C;IAC9C,SAAS,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC,CAAC;IAClD,mDAAmD;IACnD,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AA6CD;;;;;;;;;;GAUG;AACH,wBAAgB,qBAAqB,CACnC,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,cAAc,EACvB,IAAI,GAAE,mBAAwB,GAC7B;IAAE,QAAQ,EAAE,aAAa,CAAC;IAAC,UAAU,EAAE,iBAAiB,CAAA;CAAE,CAuB5D;AAED,MAAM,WAAW,qBAAqB;IACpC,UAAU,EAAE,MAAM,CAAC;IACnB,kDAAkD;IAClD,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,wEAAwE;IACxE,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,0DAA0D;IAC1D,MAAM,CAAC,EAAE,eAAe,CAAC;IACzB,oFAAoF;IACpF,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACvC,sFAAsF;IACtF,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,oFAAoF;IACpF,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,8FAA8F;IAC9F,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,uGAAuG;IACvG,kBAAkB,CAAC,EAAE,SAAS,GAAG,YAAY,CAAC;CAC/C;AAED,wBAAgB,sBAAsB,CACpC,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,cAAc,EACvB,IAAI,GAAE,qBAAsC,GAC3C,CAAC,CAAC,GAAG,EAAE,OAAO,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAC,GAAG;IAAE,KAAK,CAAC,EAAE,OAAO,CAAC,IAAI,CAAC,CAAA;CAAE,CAqZnE;AAGD,YAAY,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAC;AAChE,OAAO,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC"}
|
|
@@ -20,6 +20,7 @@ import { HealthHandler } from "../handlers/monitoring/health.handler.js";
|
|
|
20
20
|
import { MetricsHandler } from "../handlers/monitoring/metrics.handler.js";
|
|
21
21
|
import { finalizeRequestProfiling, runWithRequestProfiling, updateRequestProfileContext, withServerTimingHeader, } from "../../observability/request-profiler.js";
|
|
22
22
|
import { profilePhase } from "../../observability/index.js";
|
|
23
|
+
import { captureApplicationError } from "../../observability/application-errors.js";
|
|
23
24
|
import { ClientLogHandler } from "../handlers/monitoring/client-log.handler.js";
|
|
24
25
|
import { MemoryDebugHandler } from "../handlers/monitoring/memory.handler.js";
|
|
25
26
|
import { DevEndpointsHandler } from "../handlers/dev/endpoints.handler.js";
|
|
@@ -52,7 +53,7 @@ import { ChannelInvokeHandler } from "../handlers/request/channel-invoke.handler
|
|
|
52
53
|
import { DevDashboardHandler } from "../handlers/dev/dashboard/index.js";
|
|
53
54
|
import { ProjectsHandler } from "../handlers/dev/projects/index.js";
|
|
54
55
|
// Extracted modules
|
|
55
|
-
import { endRequestTracing, executeWithTracingContext, setProjectAttributes, setRequestAttributes, SpanNames, startRequestTracing, withSpan, } from "./tracing.js";
|
|
56
|
+
import { endRequestTracing, executeWithTracingContext, getRequestTraceContext, setProjectAttributes, setRequestAttributes, SpanNames, startRequestTracing, withSpan, } from "./tracing.js";
|
|
56
57
|
import { completeRequestTracking, completeRequestTrackingOnResponseEnd, endContentMetrics, endRequestLifecycle, incrementRequestMetrics, startContentMetrics, startRequestLifecycle, startRequestTracking, timeAsync, } from "./request-lifecycle.js";
|
|
57
58
|
import { checkRequestIsolation, completeIsolatedRequest, completeIsolatedRequestOnSettlement, createIsolationErrorResponse, startIsolatedRequest, } from "./isolation.js";
|
|
58
59
|
import { defaultDiscoveryCache } from "./local-project-discovery.js";
|
|
@@ -442,6 +443,14 @@ export function createVeryfrontHandler(projectDir, adapter, opts = { projectDir
|
|
|
442
443
|
}
|
|
443
444
|
});
|
|
444
445
|
}, url.pathname, req.method, { signal: req.signal });
|
|
446
|
+
if (error) {
|
|
447
|
+
captureApplicationError(error, {
|
|
448
|
+
boundary: "renderer.request",
|
|
449
|
+
method: req.method,
|
|
450
|
+
requestId: lifecycle.requestId,
|
|
451
|
+
...getRequestTraceContext(spanInfo.span),
|
|
452
|
+
});
|
|
453
|
+
}
|
|
445
454
|
endRequestTracing(spanInfo.span, response.status, error);
|
|
446
455
|
endContentMetrics({
|
|
447
456
|
requestId: lifecycle.requestId,
|
|
@@ -31,6 +31,10 @@ export declare function setProjectAttributes(span: unknown, projectSlug: string
|
|
|
31
31
|
* End the server span with status and optional error.
|
|
32
32
|
*/
|
|
33
33
|
export declare function endRequestTracing(span: unknown, status: number, error?: Error): void;
|
|
34
|
+
export declare function getRequestTraceContext(span: unknown): {
|
|
35
|
+
traceId?: string;
|
|
36
|
+
spanId?: string;
|
|
37
|
+
};
|
|
34
38
|
/**
|
|
35
39
|
* Execute a handler with the span's context.
|
|
36
40
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tracing.d.ts","sourceRoot":"","sources":["../../../../src/src/server/runtime-handler/tracing.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAML,QAAQ,EACT,MAAM,2CAA2C,CAAC;AACnD,OAAO,EAAE,SAAS,EAAE,MAAM,8BAA8B,CAAC;AAEzD,UAAU,QAAQ;IAChB,qDAAqD;IACrD,IAAI,EAAE,OAAO,CAAC;IACd,sDAAsD;IACtD,OAAO,EAAE,OAAO,CAAC;CAClB;
|
|
1
|
+
{"version":3,"file":"tracing.d.ts","sourceRoot":"","sources":["../../../../src/src/server/runtime-handler/tracing.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAML,QAAQ,EACT,MAAM,2CAA2C,CAAC;AACnD,OAAO,EAAE,SAAS,EAAE,MAAM,8BAA8B,CAAC;AAEzD,UAAU,QAAQ;IAChB,qDAAqD;IACrD,IAAI,EAAE,OAAO,CAAC;IACd,sDAAsD;IACtD,OAAO,EAAE,OAAO,CAAC;CAClB;AAMD;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,GAAG,QAAQ,CAQ5E;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,GAAG,GAAG,IAAI,CAQhF;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,OAAO,EACb,WAAW,EAAE,MAAM,GAAG,SAAS,EAC/B,WAAW,EAAE,MAAM,GAAG,SAAS,GAC9B,IAAI,CAON;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,KAAK,GAAG,IAAI,CAEpF;AAED,wBAAgB,sBAAsB,CACpC,IAAI,EAAE,OAAO,GACZ;IAAE,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,CAUvC;AAED;;GAEG;AACH,wBAAgB,yBAAyB,CAAC,CAAC,EACzC,QAAQ,EAAE,QAAQ,EAClB,OAAO,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GACxB,OAAO,CAAC,CAAC,CAAC,CAKZ;AAED;;GAEG;AACH,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,CAAC"}
|
|
@@ -49,6 +49,14 @@ export function setProjectAttributes(span, projectSlug, environment) {
|
|
|
49
49
|
export function endRequestTracing(span, status, error) {
|
|
50
50
|
endServerSpan(span, status, error);
|
|
51
51
|
}
|
|
52
|
+
export function getRequestTraceContext(span) {
|
|
53
|
+
if (!span || typeof span !== "object" || !("spanContext" in span) ||
|
|
54
|
+
typeof span.spanContext !== "function") {
|
|
55
|
+
return {};
|
|
56
|
+
}
|
|
57
|
+
const context = span.spanContext();
|
|
58
|
+
return { traceId: context.traceId, spanId: context.spanId };
|
|
59
|
+
}
|
|
52
60
|
/**
|
|
53
61
|
* Execute a handler with the span's context.
|
|
54
62
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ssr.service.d.ts","sourceRoot":"","sources":["../../../../../src/src/server/services/rendering/ssr.service.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAC9D,OAAO,EAEL,KAAK,eAAe,EAErB,MAAM,kCAAkC,CAAC;
|
|
1
|
+
{"version":3,"file":"ssr.service.d.ts","sourceRoot":"","sources":["../../../../../src/src/server/services/rendering/ssr.service.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAC9D,OAAO,EAEL,KAAK,eAAe,EAErB,MAAM,kCAAkC,CAAC;AAyB1C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AAItE;;;GAGG;AACH,MAAM,WAAW,gBAAgB;IAC/B,WAAW,CAAC,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC;CAC5D;AAED;;;GAGG;AACH,MAAM,WAAW,cAAc;IAC7B,mBAAmB,IAAI,YAAY,CAAC;IACpC,UAAU,CAAC,GAAG,EAAE,cAAc,EAAE,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC;IACrF,0BAA0B,CAAC,IAAI,EAAE,MAAM,GAAG,eAAe,CAAC;CAC3D;AAUD,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,cAAc,CAAC,UAAU,CAAC,CAAC;IACpC,WAAW,EAAE,OAAO,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,aAAa,EAAE,UAAU,GAAG,OAAO,CAAC;IACpC,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,SAAS,CAAC,EACN,WAAW,GACX,YAAY,GACZ,UAAU,GACV,cAAc,GACd,SAAS,GACT,2BAA2B,CAAC;IAChC,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,OAAO,CAAC;IACjB,GAAG,EAAE,GAAG,CAAC;IACT,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,OAAO,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,OAAO,CAAC;IACf,sBAAsB,CAAC,EAAE,OAAO,CAAC;IACjC,UAAU,EAAE,OAAO,CAAC;CACrB;AAED,MAAM,WAAW,YAAY;IAC3B,YAAY,EAAE,OAAO,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,MAAM,CAAC;CACzB;AA4FD,qBAAa,UAAW,YAAW,cAAc;IAC/C,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAC,CAA0B;IACrD,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAmB;gBAExC,OAAO,CAAC,EAAE;QACpB,SAAS,CAAC,EAAE,eAAe,CAAC,MAAM,CAAC,CAAC;QACpC,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;KACrC;IAKD,mBAAmB,IAAI,YAAY;IAW7B,WAAW,CAAC,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,eAAe,CAAC;IAI1D,UAAU,CAAC,GAAG,EAAE,cAAc,EAAE,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,eAAe,CAAC;IA6H1F,OAAO,CAAC,iBAAiB;IAmKzB,0BAA0B,CAAC,IAAI,EAAE,MAAM,GAAG,eAAe;CAS1D"}
|
|
@@ -7,6 +7,7 @@ import { isDataControlResult } from "../../../data/helpers.js";
|
|
|
7
7
|
import { getColorSchemeFromRequest } from "../../../security/http/client-hints.js";
|
|
8
8
|
import { endRenderSession, hasRenderSession, runInRenderSession, startRenderSession, } from "../../../transforms/mdx/esm-module-loader/module-fetcher/index.js";
|
|
9
9
|
import { getErrorCollector, profilePhase } from "../../../observability/index.js";
|
|
10
|
+
import { captureApplicationError } from "../../../observability/application-errors.js";
|
|
10
11
|
import { ErrorOverlay, parseErrorLocation } from "../../dev-server/error-overlay/index.js";
|
|
11
12
|
import { ErrorPages } from "../../utils/error-html.js";
|
|
12
13
|
import { HTTP_INTERNAL_SERVER_ERROR, HTTP_NOT_FOUND, HTTP_OK, HTTP_REDIRECT_FOUND, HTTP_UNAVAILABLE, } from "../../../utils/constants/index.js";
|
|
@@ -212,10 +213,15 @@ export class SSRService {
|
|
|
212
213
|
}
|
|
213
214
|
}
|
|
214
215
|
handleRenderError(error, ctx, slug, request, nonce) {
|
|
216
|
+
const errorObj = error instanceof Error ? error : new Error(String(error));
|
|
215
217
|
// The page threw and its app-router error.tsx already rendered a full,
|
|
216
218
|
// hydrating document (the boundary UI). Serve it as a 500 without caching.
|
|
217
219
|
const errorBoundaryHtml = error?.errorBoundaryHtml;
|
|
218
220
|
if (typeof errorBoundaryHtml === "string") {
|
|
221
|
+
captureApplicationError(errorObj, {
|
|
222
|
+
boundary: "ssr.app-router-error-boundary",
|
|
223
|
+
method: request.method,
|
|
224
|
+
});
|
|
219
225
|
return {
|
|
220
226
|
status: HTTP_INTERNAL_SERVER_ERROR,
|
|
221
227
|
html: errorBoundaryHtml,
|
|
@@ -225,7 +231,6 @@ export class SSRService {
|
|
|
225
231
|
slug,
|
|
226
232
|
};
|
|
227
233
|
}
|
|
228
|
-
const errorObj = error instanceof Error ? error : new Error(String(error));
|
|
229
234
|
// Dev-only overlay (full stack, absolute paths, line numbers) must never
|
|
230
235
|
// be exposed outside a local project, including remote preview, which is
|
|
231
236
|
// internet-reachable. See VULN-SRV-1 / VULN-SRV-2.
|
|
@@ -296,6 +301,10 @@ export class SSRService {
|
|
|
296
301
|
slug,
|
|
297
302
|
};
|
|
298
303
|
}
|
|
304
|
+
captureApplicationError(errorObj, {
|
|
305
|
+
boundary: "ssr.render",
|
|
306
|
+
method: request.method,
|
|
307
|
+
});
|
|
299
308
|
logger.error("Render failed", {
|
|
300
309
|
slug,
|
|
301
310
|
error: errorObj.message,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "veryfront",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.1165",
|
|
4
4
|
"description": "The simplest way to build AI-powered apps",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"react",
|
|
@@ -185,6 +185,10 @@
|
|
|
185
185
|
"import": "./esm/src/observability/index.js",
|
|
186
186
|
"types": "./esm/src/observability/index.d.ts"
|
|
187
187
|
},
|
|
188
|
+
"./observability/sentry": {
|
|
189
|
+
"import": "./esm/src/observability/sentry.js",
|
|
190
|
+
"types": "./esm/src/observability/sentry.d.ts"
|
|
191
|
+
},
|
|
188
192
|
"./observability/otlp-setup": {
|
|
189
193
|
"import": "./esm/src/observability/tracing/otlp-setup.js",
|
|
190
194
|
"types": "./esm/src/observability/tracing/otlp-setup.d.ts"
|
|
@@ -332,10 +336,10 @@
|
|
|
332
336
|
"@types/react": "19.2.14",
|
|
333
337
|
"@types/react-dom": "19.2.3",
|
|
334
338
|
"ws": "8.21.0",
|
|
335
|
-
"@veryfront/ext-bundler-esbuild": "0.1.
|
|
336
|
-
"@veryfront/ext-content-mdx": "0.1.
|
|
337
|
-
"@veryfront/ext-css-tailwind": "0.1.
|
|
338
|
-
"@veryfront/ext-parser-babel": "0.1.
|
|
339
|
+
"@veryfront/ext-bundler-esbuild": "0.1.1165",
|
|
340
|
+
"@veryfront/ext-content-mdx": "0.1.1165",
|
|
341
|
+
"@veryfront/ext-css-tailwind": "0.1.1165",
|
|
342
|
+
"@veryfront/ext-parser-babel": "0.1.1165"
|
|
339
343
|
},
|
|
340
344
|
"devDependencies": {
|
|
341
345
|
"@types/node": "20.9.0"
|