veryfront 0.1.1162 → 0.1.1164

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.
@@ -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;AA+FD,wBAAsB,YAAY,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAcvE"}
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.1162",
3
+ "version": "0.1.1164",
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
+ }
@@ -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;AAkCpD,OAAO,EAAE,iBAAiB,EAAE,MAAM,kCAAkC,CAAC;AAuErE,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,CA4YnE;AAGD,YAAY,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAC;AAChE,OAAO,EAAE,WAAW,EAAE,MAAM,8BAA8B,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;AAED;;;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;;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"}
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;AAwB1C,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;IAyJzB,0BAA0B,CAAC,IAAI,EAAE,MAAM,GAAG,eAAe;CAS1D"}
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,
@@ -1,3 +1,3 @@
1
1
  /** Shared version value. */
2
- export declare const VERSION = "0.1.1162";
2
+ export declare const VERSION = "0.1.1164";
3
3
  //# sourceMappingURL=version-constant.d.ts.map
@@ -1,4 +1,4 @@
1
1
  // Keep in sync with deno.json version.
2
2
  // scripts/release.ts updates this constant during releases.
3
3
  /** Shared version value. */
4
- export const VERSION = "0.1.1162";
4
+ export const VERSION = "0.1.1164";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "veryfront",
3
- "version": "0.1.1162",
3
+ "version": "0.1.1164",
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.1162",
336
- "@veryfront/ext-content-mdx": "0.1.1162",
337
- "@veryfront/ext-css-tailwind": "0.1.1162",
338
- "@veryfront/ext-parser-babel": "0.1.1162"
339
+ "@veryfront/ext-bundler-esbuild": "0.1.1164",
340
+ "@veryfront/ext-content-mdx": "0.1.1164",
341
+ "@veryfront/ext-css-tailwind": "0.1.1164",
342
+ "@veryfront/ext-parser-babel": "0.1.1164"
339
343
  },
340
344
  "devDependencies": {
341
345
  "@types/node": "20.9.0"