veryfront 0.1.777 → 0.1.779
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/deno.js +1 -1
- package/esm/src/observability/request-profiler.d.ts +8 -1
- package/esm/src/observability/request-profiler.d.ts.map +1 -1
- package/esm/src/observability/request-profiler.js +53 -4
- package/esm/src/server/runtime-handler/index.d.ts.map +1 -1
- package/esm/src/server/runtime-handler/index.js +50 -44
- package/esm/src/utils/version-constant.d.ts +1 -1
- package/esm/src/utils/version-constant.js +1 -1
- package/package.json +1 -1
package/esm/deno.js
CHANGED
|
@@ -11,6 +11,10 @@ export interface RequestProfileRecord {
|
|
|
11
11
|
totalMs: number;
|
|
12
12
|
phases: Record<string, number>;
|
|
13
13
|
}
|
|
14
|
+
export interface RequestProfileContextUpdate {
|
|
15
|
+
projectSlug?: string;
|
|
16
|
+
requestMode?: string;
|
|
17
|
+
}
|
|
14
18
|
export declare function isRequestProfilingEnabled(pathname?: string): boolean;
|
|
15
19
|
export declare function runWithRequestProfiling<T>(options: {
|
|
16
20
|
category: string;
|
|
@@ -21,7 +25,10 @@ export declare function runWithRequestProfiling<T>(options: {
|
|
|
21
25
|
}, fn: () => Promise<T>): Promise<T>;
|
|
22
26
|
export declare function profilePhase<T>(name: string, fn: () => Promise<T>): Promise<T>;
|
|
23
27
|
export declare function profileSyncPhase<T>(name: string, fn: () => T): T;
|
|
24
|
-
export declare function
|
|
28
|
+
export declare function updateRequestProfileContext(update: RequestProfileContextUpdate): void;
|
|
29
|
+
export declare function finalizeRequestProfiling(status?: number): RequestProfileRecord | null;
|
|
30
|
+
export declare function buildServerTimingHeader(record: RequestProfileRecord): string;
|
|
31
|
+
export declare function withServerTimingHeader(response: Response, record: RequestProfileRecord | null): Response;
|
|
25
32
|
export declare function snapshotRequestProfiles(): {
|
|
26
33
|
enabled: boolean;
|
|
27
34
|
last_sequence: number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"request-profiler.d.ts","sourceRoot":"","sources":["../../../src/src/observability/request-profiler.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,oBAAoB;IACnC,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAChC;
|
|
1
|
+
{"version":3,"file":"request-profiler.d.ts","sourceRoot":"","sources":["../../../src/src/observability/request-profiler.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,oBAAoB;IACnC,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAChC;AAED,MAAM,WAAW,2BAA2B;IAC1C,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AA0CD,wBAAgB,yBAAyB,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAIpE;AAED,wBAAsB,uBAAuB,CAAC,CAAC,EAC7C,OAAO,EAAE;IACP,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,EACD,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GACnB,OAAO,CAAC,CAAC,CAAC,CAYZ;AAED,wBAAsB,YAAY,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAWpF;AAED,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,CAAC,GAAG,CAAC,CAWhE;AAED,wBAAgB,2BAA2B,CAAC,MAAM,EAAE,2BAA2B,GAAG,IAAI,CAMrF;AAED,wBAAgB,wBAAwB,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,oBAAoB,GAAG,IAAI,CAsBrF;AAUD,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,oBAAoB,GAAG,MAAM,CAQ5E;AAED,wBAAgB,sBAAsB,CACpC,QAAQ,EAAE,QAAQ,EAClB,MAAM,EAAE,oBAAoB,GAAG,IAAI,GAClC,QAAQ,CAiBV;AAED,wBAAgB,uBAAuB,IAAI;IACzC,OAAO,EAAE,OAAO,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;IACtB,OAAO,EAAE,oBAAoB,EAAE,CAAC;CACjC,CAMA;AAED,wBAAgB,oBAAoB,IAAI,IAAI,CAG3C"}
|
|
@@ -10,14 +10,22 @@ function roundMs(value) {
|
|
|
10
10
|
function shouldEnableProfiling() {
|
|
11
11
|
return getEnv("VERYFRONT_ENABLE_PERF_PROFILING") === "1";
|
|
12
12
|
}
|
|
13
|
+
function shouldEnableServerTiming() {
|
|
14
|
+
return getEnv("VERYFRONT_ENABLE_SERVER_TIMING") === "1";
|
|
15
|
+
}
|
|
16
|
+
function isHtmlPath(pathname) {
|
|
17
|
+
return !pathname.startsWith("/_") && !pathname.startsWith("/api/") &&
|
|
18
|
+
!/\.[a-zA-Z0-9]+$/.test(pathname);
|
|
19
|
+
}
|
|
13
20
|
function shouldProfilePath(pathname) {
|
|
14
21
|
return pathname.startsWith("/bench/") ||
|
|
15
22
|
pathname.startsWith("/api/bench/") ||
|
|
16
23
|
pathname.startsWith("/_vf_styles/") ||
|
|
17
|
-
pathname.startsWith("/_vf_modules/")
|
|
24
|
+
pathname.startsWith("/_vf_modules/") ||
|
|
25
|
+
(shouldEnableServerTiming() && isHtmlPath(pathname));
|
|
18
26
|
}
|
|
19
27
|
export function isRequestProfilingEnabled(pathname) {
|
|
20
|
-
if (!shouldEnableProfiling())
|
|
28
|
+
if (!shouldEnableProfiling() && !shouldEnableServerTiming())
|
|
21
29
|
return false;
|
|
22
30
|
if (!pathname)
|
|
23
31
|
return true;
|
|
@@ -60,10 +68,19 @@ export function profileSyncPhase(name, fn) {
|
|
|
60
68
|
session.phases.set(name, roundMs((session.phases.get(name) ?? 0) + duration));
|
|
61
69
|
}
|
|
62
70
|
}
|
|
63
|
-
export function
|
|
71
|
+
export function updateRequestProfileContext(update) {
|
|
64
72
|
const session = storage.getStore();
|
|
65
73
|
if (!session)
|
|
66
74
|
return;
|
|
75
|
+
if (update.projectSlug !== undefined)
|
|
76
|
+
session.projectSlug = update.projectSlug;
|
|
77
|
+
if (update.requestMode !== undefined)
|
|
78
|
+
session.requestMode = update.requestMode;
|
|
79
|
+
}
|
|
80
|
+
export function finalizeRequestProfiling(status) {
|
|
81
|
+
const session = storage.getStore();
|
|
82
|
+
if (!session)
|
|
83
|
+
return null;
|
|
67
84
|
const record = {
|
|
68
85
|
sequence: ++sequence,
|
|
69
86
|
category: session.category,
|
|
@@ -80,10 +97,42 @@ export function finalizeRequestProfiling(status) {
|
|
|
80
97
|
records.push(record);
|
|
81
98
|
while (records.length > MAX_RECORDS)
|
|
82
99
|
records.shift();
|
|
100
|
+
return record;
|
|
101
|
+
}
|
|
102
|
+
function sanitizeMetricName(name) {
|
|
103
|
+
return name.replace(/[^A-Za-z0-9!#$%&'*+\-.^_`|~]/g, "_");
|
|
104
|
+
}
|
|
105
|
+
function formatDuration(value) {
|
|
106
|
+
return Math.max(0, roundMs(value)).toFixed(2);
|
|
107
|
+
}
|
|
108
|
+
export function buildServerTimingHeader(record) {
|
|
109
|
+
const metrics = [`total;dur=${formatDuration(record.totalMs)}`];
|
|
110
|
+
for (const [name, duration] of Object.entries(record.phases).slice(0, 20)) {
|
|
111
|
+
metrics.push(`${sanitizeMetricName(name)};dur=${formatDuration(duration)}`);
|
|
112
|
+
}
|
|
113
|
+
return metrics.join(", ");
|
|
114
|
+
}
|
|
115
|
+
export function withServerTimingHeader(response, record) {
|
|
116
|
+
if (!record || !shouldEnableServerTiming())
|
|
117
|
+
return response;
|
|
118
|
+
const value = buildServerTimingHeader(record);
|
|
119
|
+
try {
|
|
120
|
+
response.headers.set("Server-Timing", value);
|
|
121
|
+
return response;
|
|
122
|
+
}
|
|
123
|
+
catch {
|
|
124
|
+
const headers = new Headers(response.headers);
|
|
125
|
+
headers.set("Server-Timing", value);
|
|
126
|
+
return new Response(response.body, {
|
|
127
|
+
status: response.status,
|
|
128
|
+
statusText: response.statusText,
|
|
129
|
+
headers,
|
|
130
|
+
});
|
|
131
|
+
}
|
|
83
132
|
}
|
|
84
133
|
export function snapshotRequestProfiles() {
|
|
85
134
|
return {
|
|
86
|
-
enabled: shouldEnableProfiling(),
|
|
135
|
+
enabled: shouldEnableProfiling() || shouldEnableServerTiming(),
|
|
87
136
|
last_sequence: sequence,
|
|
88
137
|
records: [...records],
|
|
89
138
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/src/server/runtime-handler/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAOH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AACtE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAK7D,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;AAOH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AACtE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAK7D,OAAO,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAC;AAChE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAmCpD,OAAO,EAAE,iBAAiB,EAAE,MAAM,kCAAkC,CAAC;AAiErE,OAAO,EAAE,qBAAqB,EAAE,KAAK,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAMtF,2CAA2C;AAC3C,eAAO,MAAM,aAAa,msBAmChB,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;AA2CD;;;;;;;;;;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,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,CAqcnE;AAGD,YAAY,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAC;AAChE,OAAO,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC"}
|
|
@@ -22,7 +22,7 @@ import { CsrfHandler } from "../../security/http/csrf/csrf-handler.js";
|
|
|
22
22
|
import { CorsHandler } from "../handlers/response/cors.js";
|
|
23
23
|
import { HealthHandler } from "../handlers/monitoring/health.handler.js";
|
|
24
24
|
import { MetricsHandler } from "../handlers/monitoring/metrics.handler.js";
|
|
25
|
-
import { finalizeRequestProfiling, runWithRequestProfiling, } from "../../observability/request-profiler.js";
|
|
25
|
+
import { finalizeRequestProfiling, profilePhase, runWithRequestProfiling, updateRequestProfileContext, withServerTimingHeader, } from "../../observability/request-profiler.js";
|
|
26
26
|
import { ClientLogHandler } from "../handlers/monitoring/client-log.handler.js";
|
|
27
27
|
import { MemoryDebugHandler } from "../handlers/monitoring/memory.handler.js";
|
|
28
28
|
import { DevEndpointsHandler } from "../handlers/dev/endpoints.handler.js";
|
|
@@ -338,30 +338,39 @@ export function createVeryfrontHandler(projectDir, adapter, opts = { projectDir
|
|
|
338
338
|
return new Response(JSON.stringify(proxyGuardError), { status: 502, headers: { "Content-Type": "application/json" } });
|
|
339
339
|
}
|
|
340
340
|
}
|
|
341
|
+
const profileCategory = url.pathname.startsWith("/_vf_styles/")
|
|
342
|
+
? "css"
|
|
343
|
+
: url.pathname.startsWith("/_vf_modules/")
|
|
344
|
+
? "module"
|
|
345
|
+
: url.pathname.startsWith("/api/")
|
|
346
|
+
? "api"
|
|
347
|
+
: "html";
|
|
348
|
+
let requestProfileRecord = null;
|
|
341
349
|
const executeHandler = async () => {
|
|
342
350
|
// Fast rejection of vulnerability scanner probes before any async work
|
|
343
351
|
if (SCANNER_PATH_PATTERN.test(url.pathname)) {
|
|
344
352
|
return new Response("Not Found", { status: 404 });
|
|
345
353
|
}
|
|
346
|
-
await readyPromise;
|
|
347
|
-
await timeAsync("security:load", async () => {
|
|
354
|
+
await profilePhase("runtime.ready", () => readyPromise);
|
|
355
|
+
await timeAsync("security:load", () => profilePhase("runtime.security_load", async () => {
|
|
348
356
|
if (isProxyMode)
|
|
349
357
|
return;
|
|
350
358
|
await securityLoader.ensureLoaded();
|
|
351
|
-
});
|
|
352
|
-
await timeAsync("config:load", async () => {
|
|
359
|
+
}));
|
|
360
|
+
await timeAsync("config:load", () => profilePhase("runtime.config_load", async () => {
|
|
353
361
|
await configPromise;
|
|
354
|
-
});
|
|
362
|
+
}));
|
|
355
363
|
const reqCtx = createRequestContext(req);
|
|
356
364
|
const wsSlugOverride = url.searchParams.get("x-project-slug") || undefined;
|
|
357
365
|
// Resolve project from various sources
|
|
358
|
-
const projectRes = await resolveProject(req, url, headers, {
|
|
366
|
+
const projectRes = await profilePhase("runtime.resolve_project", () => resolveProject(req, url, headers, {
|
|
359
367
|
config,
|
|
360
368
|
reqCtx,
|
|
361
369
|
defaultProjectSlug: opts.defaultProjectSlug,
|
|
362
370
|
defaultProjectId: opts.defaultProjectId,
|
|
363
371
|
wsSlugOverride,
|
|
364
|
-
});
|
|
372
|
+
}));
|
|
373
|
+
updateRequestProfileContext({ projectSlug: projectRes.projectSlug });
|
|
365
374
|
setProjectAttributes(spanInfo.span, projectRes.projectSlug, projectRes.proxyEnv);
|
|
366
375
|
// Handle projects discovery UI
|
|
367
376
|
if (shouldHandleProjectsUI(url.pathname, projectRes.projectSlug, projectRes.parsedDomain)) {
|
|
@@ -373,7 +382,7 @@ export function createVeryfrontHandler(projectDir, adapter, opts = { projectDir
|
|
|
373
382
|
// Note: `x-project-path` is NOT forwarded via `headers.projectPath` anymore;
|
|
374
383
|
// `resolveAdapter` reads it directly from `req` and only honours it when the
|
|
375
384
|
// request is proxy-trusted (see isProxyTrusted).
|
|
376
|
-
const adapterRes = await resolveAdapter({
|
|
385
|
+
const adapterRes = await profilePhase("runtime.resolve_adapter", () => resolveAdapter({
|
|
377
386
|
req,
|
|
378
387
|
projectDir,
|
|
379
388
|
adapter,
|
|
@@ -387,7 +396,7 @@ export function createVeryfrontHandler(projectDir, adapter, opts = { projectDir
|
|
|
387
396
|
environmentName: projectRes.environmentName,
|
|
388
397
|
parsedDomain: projectRes.parsedDomain,
|
|
389
398
|
isProxyMode,
|
|
390
|
-
});
|
|
399
|
+
}));
|
|
391
400
|
// Resolve environment and validate
|
|
392
401
|
const host = req.headers.get("x-forwarded-host") || req.headers.get("host") || url.host;
|
|
393
402
|
const envRes = resolveEnvironment({
|
|
@@ -406,6 +415,7 @@ export function createVeryfrontHandler(projectDir, adapter, opts = { projectDir
|
|
|
406
415
|
if (envRes.errorResponse) {
|
|
407
416
|
return envRes.errorResponse;
|
|
408
417
|
}
|
|
418
|
+
updateRequestProfileContext({ requestMode: envRes.resolvedEnvironment });
|
|
409
419
|
const skipRenderEnrichedContext = shouldSkipEnrichedContext(url.pathname);
|
|
410
420
|
// Build handler context
|
|
411
421
|
const ctx = buildHandlerContext({
|
|
@@ -435,10 +445,12 @@ export function createVeryfrontHandler(projectDir, adapter, opts = { projectDir
|
|
|
435
445
|
headers.environmentId &&
|
|
436
446
|
reqCtx.token &&
|
|
437
447
|
projectRes.projectSlug) {
|
|
438
|
-
|
|
448
|
+
const environmentId = headers.environmentId;
|
|
449
|
+
const projectSlug = projectRes.projectSlug;
|
|
450
|
+
envVarsForRequest = await profilePhase("runtime.load_env_vars", () => envVarCache.get(environmentId, reqCtx.token, projectSlug));
|
|
439
451
|
logDebug("[runtime-handler] Project env vars fetched", {
|
|
440
|
-
projectSlug
|
|
441
|
-
environmentId
|
|
452
|
+
projectSlug,
|
|
453
|
+
environmentId,
|
|
442
454
|
count: Object.keys(envVarsForRequest).length,
|
|
443
455
|
});
|
|
444
456
|
}
|
|
@@ -448,36 +460,15 @@ export function createVeryfrontHandler(projectDir, adapter, opts = { projectDir
|
|
|
448
460
|
// reqCtx.token indicates the request came through the proxy with auth.
|
|
449
461
|
// Without it (standalone / test), host env must remain accessible.
|
|
450
462
|
const shouldIsolateEnv = !adapterRes.isLocalProject && !!reqCtx.token;
|
|
451
|
-
const response = await
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
: url.pathname.startsWith("/_vf_modules/")
|
|
455
|
-
? "module"
|
|
456
|
-
: url.pathname.startsWith("/api/")
|
|
457
|
-
? "api"
|
|
458
|
-
: "html",
|
|
459
|
-
method: req.method,
|
|
460
|
-
pathname: url.pathname,
|
|
461
|
-
projectSlug: projectRes.projectSlug,
|
|
462
|
-
requestMode: envRes.resolvedEnvironment,
|
|
463
|
-
}, async () => {
|
|
464
|
-
let routedResponse;
|
|
465
|
-
try {
|
|
466
|
-
routedResponse = await withSpan(SpanNames.HANDLER_EXECUTE, () => {
|
|
467
|
-
if (shouldIsolateEnv) {
|
|
468
|
-
return runWithProjectEnv(envVarsForRequest, executeRoute);
|
|
469
|
-
}
|
|
470
|
-
return executeRoute();
|
|
471
|
-
}, {
|
|
472
|
-
"handler.project_slug": projectRes.projectSlug || "unknown",
|
|
473
|
-
"handler.path": url.pathname,
|
|
474
|
-
"handler.method": req.method,
|
|
475
|
-
});
|
|
476
|
-
return routedResponse;
|
|
477
|
-
}
|
|
478
|
-
finally {
|
|
479
|
-
finalizeRequestProfiling(routedResponse?.status);
|
|
463
|
+
const response = await withSpan(SpanNames.HANDLER_EXECUTE, () => profilePhase("handler.execute", () => {
|
|
464
|
+
if (shouldIsolateEnv) {
|
|
465
|
+
return runWithProjectEnv(envVarsForRequest, executeRoute);
|
|
480
466
|
}
|
|
467
|
+
return executeRoute();
|
|
468
|
+
}), {
|
|
469
|
+
"handler.project_slug": projectRes.projectSlug || "unknown",
|
|
470
|
+
"handler.path": url.pathname,
|
|
471
|
+
"handler.method": req.method,
|
|
481
472
|
});
|
|
482
473
|
if (response)
|
|
483
474
|
return response;
|
|
@@ -491,7 +482,22 @@ export function createVeryfrontHandler(projectDir, adapter, opts = { projectDir
|
|
|
491
482
|
});
|
|
492
483
|
return errorToRFC9457Response(noHandlerError, ctx, req);
|
|
493
484
|
};
|
|
494
|
-
const { response, error } = await withRequestTimeout(() =>
|
|
485
|
+
const { response, error } = await withRequestTimeout(() => runWithRequestProfiling({
|
|
486
|
+
category: profileCategory,
|
|
487
|
+
method: req.method,
|
|
488
|
+
pathname: url.pathname,
|
|
489
|
+
projectSlug: headers.projectSlug,
|
|
490
|
+
requestMode: headers.environment,
|
|
491
|
+
}, async () => {
|
|
492
|
+
let profiledResponse;
|
|
493
|
+
try {
|
|
494
|
+
profiledResponse = await executeWithTracingContext(spanInfo, executeHandler);
|
|
495
|
+
return profiledResponse;
|
|
496
|
+
}
|
|
497
|
+
finally {
|
|
498
|
+
requestProfileRecord = finalizeRequestProfiling(profiledResponse?.status);
|
|
499
|
+
}
|
|
500
|
+
}), url.pathname, req.method);
|
|
495
501
|
endRequestTracing(spanInfo.span, response.status, error);
|
|
496
502
|
endContentMetrics({
|
|
497
503
|
requestId: lifecycle.requestId,
|
|
@@ -501,7 +507,7 @@ export function createVeryfrontHandler(projectDir, adapter, opts = { projectDir
|
|
|
501
507
|
const isTimeout = response.status === HTTP_GATEWAY_TIMEOUT;
|
|
502
508
|
completeRequestTracking(lifecycle.requestId, response.status, isTimeout);
|
|
503
509
|
completeIsolatedRequest(headers.projectSlug, lifecycle.shouldCheckIsolation, isTimeout);
|
|
504
|
-
return response;
|
|
510
|
+
return withServerTimingHeader(response, requestProfileRecord);
|
|
505
511
|
}
|
|
506
512
|
finally {
|
|
507
513
|
endRequestLifecycle(lifecycle);
|