@apifuse/provider-sdk 2.2.0-beta.59 → 2.2.0-beta.61
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/AUTHORING.md +33 -16
- package/CHANGELOG.md +8 -0
- package/bin/apifuse-dev.ts +7 -8
- package/bin/apifuse-pack-types.ts +22 -0
- package/bin/apifuse-perf.ts +45 -10
- package/bin/apifuse-record.ts +6 -8
- package/bin/apifuse-submit-check.ts +2 -2
- package/dist/config/loader.js +13 -12
- package/dist/define.d.ts +3 -2
- package/dist/define.js +1 -1
- package/dist/dev.js +3 -1
- package/dist/engine.d.ts +7 -6
- package/dist/engine.js +6 -6
- package/dist/error-resolution.js +21 -4
- package/dist/errors.d.ts +3 -0
- package/dist/errors.js +9 -0
- package/dist/handle-meta.d.ts +39 -0
- package/dist/handle-meta.js +29 -0
- package/dist/handle.d.ts +187 -0
- package/dist/handle.js +254 -0
- package/dist/i18n/catalog.js +21 -1
- package/dist/index.d.ts +6 -4
- package/dist/index.js +4 -3
- package/dist/lint.d.ts +3 -0
- package/dist/lint.js +388 -62
- package/dist/provider.d.ts +4 -4
- package/dist/provider.js +3 -3
- package/dist/runtime/browser.js +2 -1
- package/dist/runtime/cache.js +3 -2
- package/dist/runtime/diagnostic-env-values.d.ts +5 -0
- package/dist/runtime/diagnostic-env-values.js +57 -0
- package/dist/runtime/diagnostic-env.d.ts +11 -0
- package/dist/runtime/diagnostic-env.js +35 -0
- package/dist/runtime/diagnostic-redactor.d.ts +49 -0
- package/dist/runtime/diagnostic-redactor.js +569 -0
- package/dist/runtime/egress-lease.d.ts +2 -0
- package/dist/runtime/egress-lease.js +4 -1
- package/dist/runtime/env.js +2 -1
- package/dist/runtime/handle-wordlist.d.ts +43 -0
- package/dist/runtime/{choice-wordlist.js → handle-wordlist.js} +127 -9
- package/dist/runtime/handle.d.ts +71 -0
- package/dist/runtime/handle.js +895 -0
- package/dist/runtime/instrumentation.js +3 -0
- package/dist/runtime/native-network.d.ts +10 -1
- package/dist/runtime/native-network.js +230 -29
- package/dist/runtime/native-telemetry.d.ts +142 -0
- package/dist/runtime/native-telemetry.js +231 -0
- package/dist/runtime/ocr.js +2 -1
- package/dist/runtime/otlp.js +5 -4
- package/dist/runtime/proxy-nodemaven.js +3 -2
- package/dist/runtime/request-options.d.ts +7 -0
- package/dist/runtime/request-options.js +62 -22
- package/dist/runtime/resolver-vendors/browser.js +0 -1
- package/dist/runtime/resolver.js +3 -2
- package/dist/runtime/state.d.ts +4 -1
- package/dist/runtime/state.js +32 -17
- package/dist/runtime/stt.js +3 -2
- package/dist/runtime/trace.d.ts +5 -0
- package/dist/runtime/trace.js +115 -20
- package/dist/schema.d.ts +11 -0
- package/dist/schema.js +56 -2
- package/dist/server/index.d.ts +1 -0
- package/dist/server/index.js +1 -0
- package/dist/server/self-test-redaction.js +8 -33
- package/dist/server/sensitive-values.d.ts +26 -0
- package/dist/server/sensitive-values.js +128 -0
- package/dist/server/serve-implementation.d.ts +4 -11
- package/dist/server/serve-implementation.js +305 -96
- package/dist/server/trace-output.d.ts +2 -1
- package/dist/server/trace-output.js +46 -14
- package/dist/testing/run.js +10 -7
- package/dist/trace-sanitization.d.ts +4 -3
- package/dist/trace-sanitization.js +45 -22
- package/dist/types.d.ts +4 -107
- package/package.json +2 -1
- package/src/config/loader.ts +13 -12
- package/src/define.ts +4 -3
- package/src/dev.ts +3 -1
- package/src/engine.ts +8 -8
- package/src/error-resolution.ts +21 -4
- package/src/errors.ts +13 -0
- package/src/handle-meta.ts +58 -0
- package/src/handle.ts +529 -0
- package/src/i18n/catalog.ts +23 -1
- package/src/index.ts +28 -13
- package/src/lint.ts +456 -71
- package/src/provider.ts +10 -20
- package/src/runtime/browser.ts +2 -1
- package/src/runtime/cache.ts +3 -2
- package/src/runtime/diagnostic-env-values.ts +56 -0
- package/src/runtime/diagnostic-env.ts +55 -0
- package/src/runtime/diagnostic-redactor.ts +662 -0
- package/src/runtime/egress-lease.ts +6 -1
- package/src/runtime/env.ts +2 -1
- package/src/runtime/{choice-wordlist.ts → handle-wordlist.ts} +130 -9
- package/src/runtime/handle.ts +1162 -0
- package/src/runtime/instrumentation.ts +3 -0
- package/src/runtime/native-network.ts +281 -33
- package/src/runtime/native-telemetry.ts +366 -0
- package/src/runtime/ocr.ts +2 -1
- package/src/runtime/otlp.ts +5 -4
- package/src/runtime/proxy-nodemaven.ts +3 -2
- package/src/runtime/request-options.ts +76 -28
- package/src/runtime/resolver-vendors/browser.ts +0 -1
- package/src/runtime/resolver.ts +3 -2
- package/src/runtime/state.ts +44 -16
- package/src/runtime/stt.ts +3 -2
- package/src/runtime/trace.ts +168 -26
- package/src/schema.ts +63 -2
- package/src/server/index.ts +17 -0
- package/src/server/self-test-redaction.ts +10 -40
- package/src/server/sensitive-values.ts +197 -0
- package/src/server/serve-implementation.ts +388 -128
- package/src/server/trace-output.ts +77 -17
- package/src/testing/run.ts +11 -7
- package/src/trace-sanitization.ts +70 -23
- package/src/types.ts +4 -137
- package/dist/choice-token.d.ts +0 -24
- package/dist/choice-token.js +0 -74
- package/dist/runtime/choice-wordlist.d.ts +0 -9
- package/dist/runtime/choice.d.ts +0 -27
- package/dist/runtime/choice.js +0 -801
- package/src/choice-token.ts +0 -165
- package/src/runtime/choice.ts +0 -1197
|
@@ -1,5 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { NativeTelemetryCollector } from "../runtime/native-telemetry.js";
|
|
2
|
+
import { STATUS_CODES } from "node:http";
|
|
3
|
+
import { readDiagnosticEnv, withDiagnosticEnv } from "../runtime/diagnostic-env.js";
|
|
2
4
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
5
|
+
import { createHash } from "node:crypto";
|
|
3
6
|
import { existsSync } from "node:fs";
|
|
4
7
|
import { createRequire } from "node:module";
|
|
5
8
|
import { join } from "node:path";
|
|
@@ -8,15 +11,15 @@ import { Hono } from "hono";
|
|
|
8
11
|
import { z } from "zod";
|
|
9
12
|
import { AuthAbortError, createAuthFlowHelpers } from "../auth.js";
|
|
10
13
|
import { validateFailClosedDeclaration } from "../declaration-validation.js";
|
|
11
|
-
import { safeProviderErrorObservability } from "../error-observability.js";
|
|
12
14
|
import {
|
|
13
15
|
createInProcessProviderEngine,
|
|
14
16
|
ENGINE_OWNED_PROXY_CREDENTIAL_ENV_NAMES,
|
|
15
17
|
isEngineOwnedEnvName,
|
|
16
|
-
readEngineProxyCredentials,
|
|
17
18
|
type ProviderEngine,
|
|
18
19
|
type ProviderEngineBindingCandidates,
|
|
20
|
+
readEngineProxyCredentials,
|
|
19
21
|
} from "../engine.js";
|
|
22
|
+
import { safeProviderErrorObservability } from "../error-observability.js";
|
|
20
23
|
import {
|
|
21
24
|
SDK_OWNED_PROVIDER_ERROR_CODES,
|
|
22
25
|
SDK_RUNTIME_OWNED_ERROR_CODES,
|
|
@@ -42,20 +45,31 @@ import {
|
|
|
42
45
|
import type { ProviderLocale } from "../i18n/keys.js";
|
|
43
46
|
import {
|
|
44
47
|
categoryForStatus,
|
|
45
|
-
type ProviderErrorSource,
|
|
46
|
-
sourceForCategory,
|
|
47
48
|
isRetryableCategory,
|
|
48
49
|
PROVIDER_OBSERVABILITY_TAXONOMY_VERSION,
|
|
49
50
|
type ProviderErrorCategory,
|
|
51
|
+
type ProviderErrorSource,
|
|
52
|
+
sourceForCategory,
|
|
50
53
|
} from "../observability.js";
|
|
51
54
|
import { createScratchpad } from "../runtime/auth-flow.js";
|
|
52
55
|
import type * as BrowserRuntimeModule from "../runtime/browser.js";
|
|
53
56
|
import { createProviderCache } from "../runtime/cache.js";
|
|
54
|
-
import {
|
|
55
|
-
|
|
56
|
-
PROVIDER_RUNTIME_CHOICE_TOKEN_MASTER_SECRET_ENV,
|
|
57
|
-
} from "../runtime/choice.js";
|
|
57
|
+
import type { HandleTelemetryEvent } from "../handle.js";
|
|
58
|
+
import { createHandleContext } from "../runtime/handle.js";
|
|
58
59
|
import { createCredentialContext } from "../runtime/credential.js";
|
|
60
|
+
import {
|
|
61
|
+
bindDiagnosticSensitiveRegistry,
|
|
62
|
+
type CompiledDiagnosticSensitiveValues,
|
|
63
|
+
compileProcessDiagnosticSensitiveValues,
|
|
64
|
+
createDiagnosticRedactor,
|
|
65
|
+
type DiagnosticRedactor,
|
|
66
|
+
REDACTION_FAILED,
|
|
67
|
+
isDiagnosticRedactionSuppressed,
|
|
68
|
+
bindCriticalDiagnosticRedactor,
|
|
69
|
+
redactCriticalDiagnosticText,
|
|
70
|
+
redactDiagnosticText,
|
|
71
|
+
registerDiagnosticSensitiveValues,
|
|
72
|
+
} from "../runtime/diagnostic-redactor.js";
|
|
59
73
|
import {
|
|
60
74
|
createCeremonyEgressLeaseRuntime,
|
|
61
75
|
ENGINE_CEREMONY_EGRESS_LEASE,
|
|
@@ -65,8 +79,8 @@ import { executeOperation } from "../runtime/executor.js";
|
|
|
65
79
|
import { createHttpClient } from "../runtime/http.js";
|
|
66
80
|
import { wrapWithInstrumentation } from "../runtime/instrumentation.js";
|
|
67
81
|
import type * as NativeNetworkRuntimeModule from "../runtime/native-network.js";
|
|
68
|
-
import { getProviderBaseUrl } from "../runtime/provider.js";
|
|
69
82
|
import { createOcrClientFromEnv } from "../runtime/ocr.js";
|
|
83
|
+
import { getProviderBaseUrl } from "../runtime/provider.js";
|
|
70
84
|
import {
|
|
71
85
|
PROXY_AUTH_IP_DENIED_CODE,
|
|
72
86
|
PROXY_EDGE_AUTH_REJECTED_CODE,
|
|
@@ -78,24 +92,24 @@ import {
|
|
|
78
92
|
type ProxyTelemetryLogPayload,
|
|
79
93
|
} from "../runtime/proxy-telemetry.js";
|
|
80
94
|
import {
|
|
95
|
+
type ClosedEnum,
|
|
81
96
|
closedEnum,
|
|
82
97
|
RequestTelemetry,
|
|
83
|
-
tenantOpaqueKeys,
|
|
84
|
-
type ClosedEnum,
|
|
85
98
|
type TenantNeutral,
|
|
86
99
|
type TenantOpaqueKeys,
|
|
100
|
+
tenantOpaqueKeys,
|
|
87
101
|
} from "../runtime/request-telemetry.js";
|
|
88
|
-
import {
|
|
89
|
-
ResolverTelemetryCollector,
|
|
90
|
-
type ResolverTelemetryLogPayload,
|
|
91
|
-
} from "../runtime/resolver-telemetry.js";
|
|
92
102
|
import type * as ResolverRuntimeModule from "../runtime/resolver.js";
|
|
93
103
|
import {
|
|
94
|
-
createUnsupportedResolverClient,
|
|
95
104
|
bindResolverTelemetry,
|
|
105
|
+
createUnsupportedResolverClient,
|
|
96
106
|
inheritResolverTelemetryBinding,
|
|
97
107
|
type ResolverSolveWithRecorder,
|
|
98
108
|
} from "../runtime/resolver-shared.js";
|
|
109
|
+
import {
|
|
110
|
+
ResolverTelemetryCollector,
|
|
111
|
+
type ResolverTelemetryLogPayload,
|
|
112
|
+
} from "../runtime/resolver-telemetry.js";
|
|
99
113
|
import {
|
|
100
114
|
assertRequiredSecretsPresent,
|
|
101
115
|
listMissingRequiredSecrets,
|
|
@@ -105,9 +119,9 @@ import {
|
|
|
105
119
|
createProviderRuntimeStateFromEnv,
|
|
106
120
|
createUnsupportedProviderRuntimeState,
|
|
107
121
|
} from "../runtime/state.js";
|
|
108
|
-
import { StealthCookieJar } from "../runtime/stealth-cookies.js";
|
|
109
122
|
import type * as StealthRuntimeModule from "../runtime/stealth.js";
|
|
110
123
|
import type { StealthChallengeRuntime } from "../runtime/stealth-akamai-sbsd.js";
|
|
124
|
+
import { StealthCookieJar } from "../runtime/stealth-cookies.js";
|
|
111
125
|
import { createSttClientFromEnv } from "../runtime/stt.js";
|
|
112
126
|
import {
|
|
113
127
|
createTraceContext,
|
|
@@ -118,21 +132,21 @@ import {
|
|
|
118
132
|
} from "../runtime/trace.js";
|
|
119
133
|
import { resolveTraceConfigFromEnv } from "../runtime/trace-config.js";
|
|
120
134
|
import { parseSchema } from "../schema.js";
|
|
135
|
+
import { StatefulRoutingDeadlineError } from "../stateful/errors.js";
|
|
121
136
|
import {
|
|
122
137
|
STATEFUL_NONCE_HEADER as STATEFUL_FORWARDING_NONCE_HEADER,
|
|
123
138
|
STATEFUL_SIGNATURE_HEADER as STATEFUL_FORWARDING_SIGNATURE_HEADER,
|
|
124
139
|
STATEFUL_TIMESTAMP_HEADER as STATEFUL_FORWARDING_TIMESTAMP_HEADER,
|
|
125
140
|
verifyStatefulRequestSignature,
|
|
126
141
|
} from "../stateful-signing.js";
|
|
127
|
-
import { StatefulRoutingDeadlineError } from "../stateful/errors.js";
|
|
128
142
|
import { getStealthProfile } from "../stealth/profiles.js";
|
|
129
|
-
import { sanitizeTraceAttributes } from "../trace-sanitization.js";
|
|
130
143
|
import {
|
|
131
144
|
APIFUSE_STREAM_DONE_EVENT,
|
|
132
145
|
APIFUSE_STREAM_ERROR_EVENT,
|
|
133
146
|
encodeSseEvent,
|
|
134
147
|
error as streamError,
|
|
135
148
|
} from "../stream.js";
|
|
149
|
+
import { sanitizeSpanNameForOutput, sanitizeTraceAttributes } from "../trace-sanitization.js";
|
|
136
150
|
import type {
|
|
137
151
|
AuthContext,
|
|
138
152
|
AuthTurn,
|
|
@@ -140,15 +154,15 @@ import type {
|
|
|
140
154
|
FlowContext,
|
|
141
155
|
FlowContextStore,
|
|
142
156
|
HttpRetrySummary,
|
|
157
|
+
OcrContext,
|
|
143
158
|
OperationDefinition,
|
|
144
159
|
OperationErrorCode,
|
|
145
160
|
OperationHttpStreamTransport,
|
|
146
161
|
OperationSseTransport,
|
|
147
|
-
OcrContext,
|
|
148
|
-
ProviderErrorStatus,
|
|
149
|
-
ProviderContext,
|
|
150
162
|
ProviderCacheResponseMeta,
|
|
163
|
+
ProviderContext,
|
|
151
164
|
ProviderDefinition,
|
|
165
|
+
ProviderErrorStatus,
|
|
152
166
|
ProviderFilesContext,
|
|
153
167
|
ProviderProxyPolicy,
|
|
154
168
|
ProviderRuntimeState,
|
|
@@ -162,6 +176,10 @@ import type {
|
|
|
162
176
|
import { VALID_OPERATION_ERROR_STATUSES } from "../types.js";
|
|
163
177
|
import type { SelfTestCancellationLogEvent } from "./self-test.js";
|
|
164
178
|
import { resolveSelfTestMasterSecrets } from "./self-test-token.js";
|
|
179
|
+
import {
|
|
180
|
+
collectStaticDiagnosticSensitiveValues,
|
|
181
|
+
createDiagnosticEnvObserver,
|
|
182
|
+
} from "./sensitive-values.js";
|
|
165
183
|
import { resolveServerTraceContextOptions } from "./trace-output.js";
|
|
166
184
|
import {
|
|
167
185
|
type AuthFlowRequest,
|
|
@@ -307,9 +325,7 @@ export type ProviderServerOperationExecutorInput<
|
|
|
307
325
|
|
|
308
326
|
export type ProviderServerOperationExecutor<
|
|
309
327
|
TContext extends Partial<ProviderContext> = ProviderContext,
|
|
310
|
-
> = (
|
|
311
|
-
input: ProviderServerOperationExecutorInput<TContext>,
|
|
312
|
-
) => Promise<unknown>;
|
|
328
|
+
> = (input: ProviderServerOperationExecutorInput<TContext>) => Promise<unknown>;
|
|
313
329
|
|
|
314
330
|
type RequestTerminalOutcome =
|
|
315
331
|
| { kind: "completed"; status: number }
|
|
@@ -317,6 +333,7 @@ type RequestTerminalOutcome =
|
|
|
317
333
|
| { kind: "cancelled"; status?: number };
|
|
318
334
|
|
|
319
335
|
type RequestStreamLifecycle = {
|
|
336
|
+
redact: DiagnosticRedactor;
|
|
320
337
|
runStep<T>(fn: () => Promise<T>): Promise<T>;
|
|
321
338
|
registerCleanup(cleanup: () => void | Promise<void>): void;
|
|
322
339
|
terminalize(outcome: RequestTerminalOutcome): void;
|
|
@@ -823,9 +840,11 @@ function providerSecretNames(provider: ProviderDefinition): string[] {
|
|
|
823
840
|
}
|
|
824
841
|
|
|
825
842
|
type RequestScopeContext = {
|
|
843
|
+
redact: DiagnosticRedactor;
|
|
826
844
|
trace: RuntimeTraceContext;
|
|
827
845
|
telemetry: RequestTelemetry;
|
|
828
846
|
resolverTelemetry: ResolverTelemetryCollector;
|
|
847
|
+
nativeTelemetry: NativeTelemetryCollector;
|
|
829
848
|
};
|
|
830
849
|
|
|
831
850
|
function createProviderContext(
|
|
@@ -899,12 +918,10 @@ function createProviderContext(
|
|
|
899
918
|
request.requestId,
|
|
900
919
|
"stealth",
|
|
901
920
|
error,
|
|
921
|
+
scope.redact,
|
|
902
922
|
);
|
|
903
923
|
|
|
904
|
-
const env = createEnvContext([
|
|
905
|
-
...providerSecretNames(provider),
|
|
906
|
-
PROVIDER_RUNTIME_CHOICE_TOKEN_MASTER_SECRET_ENV,
|
|
907
|
-
]);
|
|
924
|
+
const env = createEnvContext([...providerSecretNames(provider)]);
|
|
908
925
|
const credential = createCredentialContext({
|
|
909
926
|
allowedKeys: provider.credential?.keys,
|
|
910
927
|
mode: request.connection?.mode,
|
|
@@ -940,7 +957,7 @@ function createProviderContext(
|
|
|
940
957
|
provider.runtime === "browser"
|
|
941
958
|
? capabilityModules.browser!.createBrowserClient({
|
|
942
959
|
allowedHosts: provider.allowedHosts,
|
|
943
|
-
cdpUrl:
|
|
960
|
+
cdpUrl: readDiagnosticEnv("APIFUSE__CDP_POOL__URL"),
|
|
944
961
|
headless: true,
|
|
945
962
|
requireCdpPool: isProductionProviderBrowserMode(provider),
|
|
946
963
|
stealth: true,
|
|
@@ -951,6 +968,8 @@ function createProviderContext(
|
|
|
951
968
|
? {
|
|
952
969
|
native: {
|
|
953
970
|
network: capabilityModules.nativeNetwork!.createNativeNetworkClient({
|
|
971
|
+
telemetry: scope.telemetry.proxy,
|
|
972
|
+
nativeTelemetry: scope.nativeTelemetry,
|
|
954
973
|
egress: provider.native.network,
|
|
955
974
|
proxyPolicy: resolveNativeProxyPolicy(provider),
|
|
956
975
|
affinityKey: proxyClientOptions.affinityKey,
|
|
@@ -984,16 +1003,14 @@ function createProviderContext(
|
|
|
984
1003
|
createUnsupportedResolverClient("Provider does not declare resolver capability"),
|
|
985
1004
|
signal,
|
|
986
1005
|
),
|
|
987
|
-
|
|
1006
|
+
handle: createHandleContext({
|
|
988
1007
|
providerId: provider.id,
|
|
989
|
-
env,
|
|
990
1008
|
request: requestContext,
|
|
991
|
-
credential,
|
|
992
1009
|
state: requestState,
|
|
993
1010
|
onTelemetry: (event) =>
|
|
994
1011
|
(options.logger ?? defaultProviderServerLogger)({
|
|
995
1012
|
level: "info",
|
|
996
|
-
event: "
|
|
1013
|
+
event: "provider_handle",
|
|
997
1014
|
...event,
|
|
998
1015
|
}),
|
|
999
1016
|
}),
|
|
@@ -1101,6 +1118,7 @@ function createAuthFlowContext(
|
|
|
1101
1118
|
providerId: provider.id,
|
|
1102
1119
|
flowId: request.flowId,
|
|
1103
1120
|
affinityKey: proxyClientOptions.affinityKey,
|
|
1121
|
+
onHandle: (handle) => registerDiagnosticSensitiveValues(scope.trace, [handle]),
|
|
1104
1122
|
...(request.engine?.egressLease ? { handle: request.engine.egressLease } : {}),
|
|
1105
1123
|
})
|
|
1106
1124
|
: undefined;
|
|
@@ -1161,6 +1179,7 @@ function createAuthFlowContext(
|
|
|
1161
1179
|
request.requestId,
|
|
1162
1180
|
"stealth",
|
|
1163
1181
|
error,
|
|
1182
|
+
scope.redact,
|
|
1164
1183
|
);
|
|
1165
1184
|
const credential = request.connection
|
|
1166
1185
|
? createCredentialContext({
|
|
@@ -1191,6 +1210,8 @@ function createAuthFlowContext(
|
|
|
1191
1210
|
? {
|
|
1192
1211
|
native: {
|
|
1193
1212
|
network: capabilityModules.nativeNetwork!.createNativeNetworkClient({
|
|
1213
|
+
telemetry: scope.telemetry.proxy,
|
|
1214
|
+
nativeTelemetry: scope.nativeTelemetry,
|
|
1194
1215
|
egress: provider.native.network,
|
|
1195
1216
|
proxyPolicy: resolveNativeProxyPolicy(provider),
|
|
1196
1217
|
affinityKey: proxyClientOptions.affinityKey,
|
|
@@ -1296,18 +1317,10 @@ export type ProviderServerLogEvent =
|
|
|
1296
1317
|
providerId: string;
|
|
1297
1318
|
missingSecrets: string[];
|
|
1298
1319
|
}
|
|
1299
|
-
| {
|
|
1320
|
+
| ({
|
|
1300
1321
|
level: "info";
|
|
1301
|
-
event: "
|
|
1302
|
-
|
|
1303
|
-
purpose: string;
|
|
1304
|
-
operation: "parse" | "consume";
|
|
1305
|
-
format: "word" | "legacy";
|
|
1306
|
-
outcome: "success" | "not-found" | "invalid" | "unsupported" | "error";
|
|
1307
|
-
consumeMode: "never" | "on-parse" | "explicit";
|
|
1308
|
-
consumed: boolean;
|
|
1309
|
-
replay: boolean;
|
|
1310
|
-
}
|
|
1322
|
+
event: "provider_handle";
|
|
1323
|
+
} & HandleTelemetryEvent)
|
|
1311
1324
|
| {
|
|
1312
1325
|
level: "warn";
|
|
1313
1326
|
event: "provider_cleanup_failed";
|
|
@@ -1418,15 +1431,18 @@ function finishRequestCost(input: {
|
|
|
1418
1431
|
};
|
|
1419
1432
|
}
|
|
1420
1433
|
|
|
1421
|
-
function zodDetails(
|
|
1434
|
+
function zodDetails(
|
|
1435
|
+
error: z.ZodError,
|
|
1436
|
+
redact?: DiagnosticRedactor,
|
|
1437
|
+
): Array<{
|
|
1422
1438
|
path: string;
|
|
1423
1439
|
code: string;
|
|
1424
1440
|
message: string;
|
|
1425
1441
|
}> {
|
|
1426
1442
|
return error.issues.map((issue) => ({
|
|
1427
|
-
path: issue.path.join("."),
|
|
1428
|
-
code: issue.code,
|
|
1429
|
-
message: issue.message,
|
|
1443
|
+
path: sanitizeSpanNameForOutput(issue.path.join("."), redact),
|
|
1444
|
+
code: sanitizeSpanNameForOutput(issue.code, redact),
|
|
1445
|
+
message: sanitizeSpanNameForOutput(issue.message, redact),
|
|
1430
1446
|
}));
|
|
1431
1447
|
}
|
|
1432
1448
|
|
|
@@ -1453,6 +1469,7 @@ function toErrorResponse(
|
|
|
1453
1469
|
error: unknown,
|
|
1454
1470
|
requestId: string | undefined,
|
|
1455
1471
|
observabilityDetails: ErrorObservabilityDetails,
|
|
1472
|
+
redact?: DiagnosticRedactor,
|
|
1456
1473
|
): OperationErrorResponse {
|
|
1457
1474
|
const observability = observabilityDetails;
|
|
1458
1475
|
const source = publicErrorSource(error, observability.category);
|
|
@@ -1491,7 +1508,7 @@ function toErrorResponse(
|
|
|
1491
1508
|
...(requestId ? { requestId } : {}),
|
|
1492
1509
|
retryable: observability.retryable,
|
|
1493
1510
|
source,
|
|
1494
|
-
details: zodDetails(error),
|
|
1511
|
+
details: zodDetails(error, redact),
|
|
1495
1512
|
},
|
|
1496
1513
|
};
|
|
1497
1514
|
}
|
|
@@ -1523,6 +1540,48 @@ function toErrorResponse(
|
|
|
1523
1540
|
// narrowing from a ProviderError-typed value would collapse the negative branch
|
|
1524
1541
|
// to `never`. Narrowing from unknown avoids that while still recognizing errors
|
|
1525
1542
|
// from a duplicate SDK module instance.
|
|
1543
|
+
function ownErrorCode(error: unknown): string | undefined {
|
|
1544
|
+
if (error === null || (typeof error !== "object" && typeof error !== "function")) {
|
|
1545
|
+
return undefined;
|
|
1546
|
+
}
|
|
1547
|
+
try {
|
|
1548
|
+
const descriptor = Object.getOwnPropertyDescriptor(error, "code");
|
|
1549
|
+
return descriptor && Object.hasOwn(descriptor, "value") && typeof descriptor.value === "string"
|
|
1550
|
+
? descriptor.value
|
|
1551
|
+
: undefined;
|
|
1552
|
+
} catch {
|
|
1553
|
+
return undefined;
|
|
1554
|
+
}
|
|
1555
|
+
}
|
|
1556
|
+
|
|
1557
|
+
function errorChainHasCode(error: unknown, expected: string): boolean {
|
|
1558
|
+
const seen = new Set<object>();
|
|
1559
|
+
let current = error;
|
|
1560
|
+
for (let depth = 0; depth < 5; depth++) {
|
|
1561
|
+
if (current === null || (typeof current !== "object" && typeof current !== "function")) {
|
|
1562
|
+
return false;
|
|
1563
|
+
}
|
|
1564
|
+
if (seen.has(current)) return false;
|
|
1565
|
+
seen.add(current);
|
|
1566
|
+
let code: string | undefined;
|
|
1567
|
+
try {
|
|
1568
|
+
code = providerErrorCode(current) ?? ownErrorCode(current);
|
|
1569
|
+
} catch {
|
|
1570
|
+
code = ownErrorCode(current);
|
|
1571
|
+
}
|
|
1572
|
+
if (code === expected) return true;
|
|
1573
|
+
let cause: PropertyDescriptor | undefined;
|
|
1574
|
+
try {
|
|
1575
|
+
cause = Object.getOwnPropertyDescriptor(current, "cause");
|
|
1576
|
+
} catch {
|
|
1577
|
+
return false;
|
|
1578
|
+
}
|
|
1579
|
+
if (!cause || !Object.hasOwn(cause, "value")) return false;
|
|
1580
|
+
current = cause.value;
|
|
1581
|
+
}
|
|
1582
|
+
return false;
|
|
1583
|
+
}
|
|
1584
|
+
|
|
1526
1585
|
function providerObservabilityDetails(
|
|
1527
1586
|
error: unknown,
|
|
1528
1587
|
declaredErrorCode?: OperationErrorCode,
|
|
@@ -1551,26 +1610,45 @@ function providerObservabilityDetails(
|
|
|
1551
1610
|
retryable: providerErrorOption(error, "retryable") ?? declaredRetryable ?? false,
|
|
1552
1611
|
};
|
|
1553
1612
|
}
|
|
1613
|
+
// Native proxy resolution throws ProxyResolutionError directly, while HTTP
|
|
1614
|
+
// normalizes it beneath a transport_network_error cause and stealth retains
|
|
1615
|
+
// the original code. Preserve proxy attribution across all three forms.
|
|
1616
|
+
if (errorChainHasCode(error, "PROXY_REQUIRED")) {
|
|
1617
|
+
return {
|
|
1618
|
+
category: "proxy_pool",
|
|
1619
|
+
taxonomyVersion: PROVIDER_OBSERVABILITY_TAXONOMY_VERSION,
|
|
1620
|
+
retryable: true,
|
|
1621
|
+
};
|
|
1622
|
+
}
|
|
1554
1623
|
if (!isTransportError(error)) {
|
|
1555
1624
|
return undefined;
|
|
1556
1625
|
}
|
|
1626
|
+
const errorCode = providerErrorCode(error);
|
|
1557
1627
|
const isProxyPoolCode =
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
|
|
1628
|
+
errorCode === PROXY_POOL_EXHAUSTED_CODE ||
|
|
1629
|
+
errorCode === PROXY_EDGE_AUTH_REJECTED_CODE ||
|
|
1630
|
+
errorCode === "PROXY_ALLOCATION_FAILED" ||
|
|
1631
|
+
errorCode === "native_proxy_expired" ||
|
|
1632
|
+
errorCode === "native_proxy_invalid";
|
|
1561
1633
|
const category =
|
|
1562
1634
|
providerErrorOption(error, "category") ??
|
|
1563
1635
|
(isProxyPoolCode
|
|
1564
1636
|
? "proxy_pool"
|
|
1565
|
-
:
|
|
1637
|
+
: errorCode === PROXY_AUTH_IP_DENIED_CODE
|
|
1566
1638
|
? "anti_bot_blocked"
|
|
1567
|
-
:
|
|
1639
|
+
: errorCode === "transport_timeout" ||
|
|
1640
|
+
errorCode === "native_connection_timeout" ||
|
|
1641
|
+
errorCode === "native_connection_idle_timeout"
|
|
1568
1642
|
? "timeout"
|
|
1569
|
-
:
|
|
1643
|
+
: errorCode === "transport_network_error" ||
|
|
1644
|
+
errorCode === "native_connection_failed" ||
|
|
1645
|
+
errorCode === "native_connection_closed"
|
|
1570
1646
|
? "network"
|
|
1571
|
-
:
|
|
1572
|
-
?
|
|
1573
|
-
:
|
|
1647
|
+
: errorCode === "native_connection_aborted"
|
|
1648
|
+
? "client_cancelled"
|
|
1649
|
+
: error.upstreamStatus
|
|
1650
|
+
? categoryForStatus(error.upstreamStatus)
|
|
1651
|
+
: "upstream_http");
|
|
1574
1652
|
return {
|
|
1575
1653
|
category,
|
|
1576
1654
|
taxonomyVersion: PROVIDER_OBSERVABILITY_TAXONOMY_VERSION,
|
|
@@ -1787,14 +1865,17 @@ export type ProviderErrorCauseFrame = {
|
|
|
1787
1865
|
const MAX_PROVIDER_ERROR_CAUSE_FRAMES = 5;
|
|
1788
1866
|
const MAX_PROVIDER_ERROR_CAUSE_MESSAGE_LENGTH = 300;
|
|
1789
1867
|
|
|
1790
|
-
function providerErrorCauseMessage(message: string): string {
|
|
1791
|
-
const sanitized = sanitizeDiagnosticText(message);
|
|
1868
|
+
function providerErrorCauseMessage(message: string, redact?: DiagnosticRedactor): string {
|
|
1869
|
+
const sanitized = sanitizeDiagnosticText(redactDiagnosticText(message, redact));
|
|
1792
1870
|
return sanitized.length > MAX_PROVIDER_ERROR_CAUSE_MESSAGE_LENGTH
|
|
1793
1871
|
? `${sanitized.slice(0, MAX_PROVIDER_ERROR_CAUSE_MESSAGE_LENGTH)}… [truncated]`
|
|
1794
1872
|
: sanitized;
|
|
1795
1873
|
}
|
|
1796
1874
|
|
|
1797
|
-
function providerErrorCauseChain(
|
|
1875
|
+
function providerErrorCauseChain(
|
|
1876
|
+
error: unknown,
|
|
1877
|
+
redact?: DiagnosticRedactor,
|
|
1878
|
+
): ProviderErrorCauseFrame[] | undefined {
|
|
1798
1879
|
if (!(error instanceof Error) && !isProviderError(error)) return undefined;
|
|
1799
1880
|
|
|
1800
1881
|
const seen = new Set<object>([error]);
|
|
@@ -1811,9 +1892,9 @@ function providerErrorCauseChain(error: unknown): ProviderErrorCauseFrame[] | un
|
|
|
1811
1892
|
const providerObservability = safeProviderErrorObservability(cause);
|
|
1812
1893
|
const causeCode = providerErrorCode(cause);
|
|
1813
1894
|
frames.push({
|
|
1814
|
-
errorClass: cause.name,
|
|
1815
|
-
...(causeCode !== undefined ? { code: causeCode } : {}),
|
|
1816
|
-
message: providerErrorCauseMessage(message),
|
|
1895
|
+
errorClass: redactDiagnosticText(cause.name, redact),
|
|
1896
|
+
...(causeCode !== undefined ? { code: redactDiagnosticText(causeCode, redact) } : {}),
|
|
1897
|
+
message: providerErrorCauseMessage(message, redact),
|
|
1817
1898
|
messageLength: message.length,
|
|
1818
1899
|
messageFingerprint: createHash("sha256").update(message).digest("hex").slice(0, 12),
|
|
1819
1900
|
...(providerObservability ? { providerObservability } : {}),
|
|
@@ -1837,6 +1918,7 @@ function logProviderError(
|
|
|
1837
1918
|
telemetry: RequestTelemetry | undefined,
|
|
1838
1919
|
observabilityDetails: ErrorObservabilityDetails,
|
|
1839
1920
|
correlation: RequestCorrelationIds = {},
|
|
1921
|
+
redact?: DiagnosticRedactor,
|
|
1840
1922
|
): void {
|
|
1841
1923
|
const providerCode = isProviderError(error) ? providerErrorCode(error) : undefined;
|
|
1842
1924
|
const code = isProviderError(error)
|
|
@@ -1848,7 +1930,7 @@ function logProviderError(
|
|
|
1848
1930
|
: "internal_error";
|
|
1849
1931
|
const errorClass = error instanceof Error ? error.name : typeof error;
|
|
1850
1932
|
const message = error instanceof Error ? error.message : String(error);
|
|
1851
|
-
const causeChain = providerErrorCauseChain(error);
|
|
1933
|
+
const causeChain = providerErrorCauseChain(error, redact);
|
|
1852
1934
|
const details = observabilityDetails;
|
|
1853
1935
|
const isUnregisteredProviderErrorCode =
|
|
1854
1936
|
status === 500 &&
|
|
@@ -1868,24 +1950,28 @@ function logProviderError(
|
|
|
1868
1950
|
emit({
|
|
1869
1951
|
level: status >= 500 ? "error" : "warn",
|
|
1870
1952
|
event: "provider_request_failed",
|
|
1871
|
-
providerId: provider.id,
|
|
1953
|
+
providerId: redactDiagnosticText(provider.id, redact),
|
|
1872
1954
|
kind,
|
|
1873
|
-
route,
|
|
1874
|
-
...(requestId ? { requestId } : {}),
|
|
1955
|
+
route: redactCriticalDiagnosticText(route, redact),
|
|
1956
|
+
...(requestId ? { requestId: redactCriticalDiagnosticText(requestId, redact) } : {}),
|
|
1875
1957
|
...(correlation.connectionId !== undefined
|
|
1876
|
-
? { connectionId: correlation.connectionId }
|
|
1958
|
+
? { connectionId: redactDiagnosticText(correlation.connectionId, redact) }
|
|
1959
|
+
: {}),
|
|
1960
|
+
...(correlation.flowId !== undefined
|
|
1961
|
+
? { flowId: redactDiagnosticText(correlation.flowId, redact) }
|
|
1962
|
+
: {}),
|
|
1963
|
+
...(correlation.tenantId !== undefined
|
|
1964
|
+
? { tenantId: redactDiagnosticText(correlation.tenantId, redact) }
|
|
1877
1965
|
: {}),
|
|
1878
|
-
...(correlation.flowId !== undefined ? { flowId: correlation.flowId } : {}),
|
|
1879
|
-
...(correlation.tenantId !== undefined ? { tenantId: correlation.tenantId } : {}),
|
|
1880
1966
|
...(correlation.requestedProviderId !== undefined
|
|
1881
|
-
? { requestedProviderId: correlation.requestedProviderId }
|
|
1967
|
+
? { requestedProviderId: redactDiagnosticText(correlation.requestedProviderId, redact) }
|
|
1882
1968
|
: {}),
|
|
1883
1969
|
status,
|
|
1884
1970
|
...cost,
|
|
1885
1971
|
...(telemetryPayload ?? {}),
|
|
1886
|
-
code,
|
|
1887
|
-
errorClass,
|
|
1888
|
-
message,
|
|
1972
|
+
code: sanitizeSpanNameForOutput(redactCriticalDiagnosticText(code, redact)),
|
|
1973
|
+
errorClass: redactDiagnosticText(errorClass, redact),
|
|
1974
|
+
message: sanitizeDiagnosticText(redactDiagnosticText(message, redact)),
|
|
1889
1975
|
...(causeChain ? { causeChain } : {}),
|
|
1890
1976
|
...(providerObservability ? { providerObservability } : {}),
|
|
1891
1977
|
...(details.upstreamStatus ? { upstreamStatus: details.upstreamStatus } : {}),
|
|
@@ -1899,7 +1985,7 @@ function logProviderError(
|
|
|
1899
1985
|
"Declare this code (with status and retryable) in the operation's errorCodes so it serves its intended status instead of 500.",
|
|
1900
1986
|
}
|
|
1901
1987
|
: {}),
|
|
1902
|
-
...(error instanceof z.ZodError ? { issues: zodDetails(error) } : {}),
|
|
1988
|
+
...(error instanceof z.ZodError ? { issues: zodDetails(error, redact) } : {}),
|
|
1903
1989
|
});
|
|
1904
1990
|
}
|
|
1905
1991
|
|
|
@@ -1911,6 +1997,7 @@ function logProviderCleanupError(
|
|
|
1911
1997
|
requestId: string | undefined,
|
|
1912
1998
|
resource: "browser" | "stealth",
|
|
1913
1999
|
error: unknown,
|
|
2000
|
+
redact?: DiagnosticRedactor,
|
|
1914
2001
|
): void {
|
|
1915
2002
|
const emit = typeof logger === "function" ? logger : defaultProviderServerLogger;
|
|
1916
2003
|
const errorClass = error instanceof Error ? error.name : typeof error;
|
|
@@ -1918,13 +2005,13 @@ function logProviderCleanupError(
|
|
|
1918
2005
|
emit({
|
|
1919
2006
|
level: "warn",
|
|
1920
2007
|
event: "provider_cleanup_failed",
|
|
1921
|
-
providerId: provider.id,
|
|
2008
|
+
providerId: redactDiagnosticText(provider.id, redact),
|
|
1922
2009
|
kind,
|
|
1923
|
-
route: operationId,
|
|
1924
|
-
...(requestId ? { requestId } : {}),
|
|
2010
|
+
route: redactCriticalDiagnosticText(operationId, redact),
|
|
2011
|
+
...(requestId ? { requestId: redactCriticalDiagnosticText(requestId, redact) } : {}),
|
|
1925
2012
|
resource,
|
|
1926
|
-
errorClass,
|
|
1927
|
-
message,
|
|
2013
|
+
errorClass: redactDiagnosticText(errorClass, redact),
|
|
2014
|
+
message: sanitizeDiagnosticText(redactDiagnosticText(message, redact)),
|
|
1928
2015
|
});
|
|
1929
2016
|
}
|
|
1930
2017
|
|
|
@@ -1938,23 +2025,28 @@ function logProviderSuccess(
|
|
|
1938
2025
|
cost: ProviderRequestCost,
|
|
1939
2026
|
telemetry?: RequestTelemetry,
|
|
1940
2027
|
correlation: RequestCorrelationIds = {},
|
|
2028
|
+
redact?: DiagnosticRedactor,
|
|
1941
2029
|
): void {
|
|
1942
2030
|
const telemetryPayload = telemetry?.toLogPayload();
|
|
1943
2031
|
const emit = typeof logger === "function" ? logger : defaultProviderServerLogger;
|
|
1944
2032
|
emit({
|
|
1945
2033
|
level: "info",
|
|
1946
2034
|
event: "provider_request_completed",
|
|
1947
|
-
providerId: provider.id,
|
|
2035
|
+
providerId: redactDiagnosticText(provider.id, redact),
|
|
1948
2036
|
kind,
|
|
1949
|
-
route,
|
|
1950
|
-
...(requestId ? { requestId } : {}),
|
|
2037
|
+
route: redactCriticalDiagnosticText(route, redact),
|
|
2038
|
+
...(requestId ? { requestId: redactCriticalDiagnosticText(requestId, redact) } : {}),
|
|
1951
2039
|
...(correlation.connectionId !== undefined
|
|
1952
|
-
? { connectionId: correlation.connectionId }
|
|
2040
|
+
? { connectionId: redactDiagnosticText(correlation.connectionId, redact) }
|
|
2041
|
+
: {}),
|
|
2042
|
+
...(correlation.flowId !== undefined
|
|
2043
|
+
? { flowId: redactDiagnosticText(correlation.flowId, redact) }
|
|
2044
|
+
: {}),
|
|
2045
|
+
...(correlation.tenantId !== undefined
|
|
2046
|
+
? { tenantId: redactDiagnosticText(correlation.tenantId, redact) }
|
|
1953
2047
|
: {}),
|
|
1954
|
-
...(correlation.flowId !== undefined ? { flowId: correlation.flowId } : {}),
|
|
1955
|
-
...(correlation.tenantId !== undefined ? { tenantId: correlation.tenantId } : {}),
|
|
1956
2048
|
...(correlation.requestedProviderId !== undefined
|
|
1957
|
-
? { requestedProviderId: correlation.requestedProviderId }
|
|
2049
|
+
? { requestedProviderId: redactDiagnosticText(correlation.requestedProviderId, redact) }
|
|
1958
2050
|
: {}),
|
|
1959
2051
|
status,
|
|
1960
2052
|
...cost,
|
|
@@ -1968,6 +2060,7 @@ type RequestScopeFinishResult = {
|
|
|
1968
2060
|
};
|
|
1969
2061
|
|
|
1970
2062
|
type RequestScope = RequestScopeContext & {
|
|
2063
|
+
seedCredentials(rawBody: unknown, kind: "operation" | "auth" | "stateful"): void;
|
|
1971
2064
|
enrich(input: {
|
|
1972
2065
|
route?: string;
|
|
1973
2066
|
requestId?: string;
|
|
@@ -2039,8 +2132,91 @@ function requestTraceId(
|
|
|
2039
2132
|
);
|
|
2040
2133
|
}
|
|
2041
2134
|
|
|
2135
|
+
/** Harvest only credential subtrees, iteratively and before schema diagnostics. */
|
|
2136
|
+
function rawRequestCredentials(
|
|
2137
|
+
rawBody: unknown,
|
|
2138
|
+
kind: "operation" | "auth" | "stateful",
|
|
2139
|
+
): { values: string[]; exhausted: boolean } {
|
|
2140
|
+
const record = (value: unknown): Record<string, unknown> | undefined =>
|
|
2141
|
+
value !== null && typeof value === "object" ? (value as Record<string, unknown>) : undefined;
|
|
2142
|
+
const own = (value: unknown, key: string): unknown => {
|
|
2143
|
+
const object = record(value);
|
|
2144
|
+
return object && Object.hasOwn(object, key) ? object[key] : undefined;
|
|
2145
|
+
};
|
|
2146
|
+
const body = kind === "stateful" ? own(rawBody, "operationRequest") : rawBody;
|
|
2147
|
+
const values: string[] = [];
|
|
2148
|
+
let remainingBytes = 64 * 1024;
|
|
2149
|
+
let exhausted = false;
|
|
2150
|
+
const add = (value: unknown): void => {
|
|
2151
|
+
if (typeof value !== "string") return;
|
|
2152
|
+
const bytes = Buffer.byteLength(value, "utf8");
|
|
2153
|
+
if (bytes > remainingBytes) {
|
|
2154
|
+
exhausted = true;
|
|
2155
|
+
return;
|
|
2156
|
+
}
|
|
2157
|
+
remainingBytes -= bytes;
|
|
2158
|
+
if (value) values.push(value);
|
|
2159
|
+
const trimmed = value.trim();
|
|
2160
|
+
if (trimmed && trimmed !== value) values.push(trimmed);
|
|
2161
|
+
};
|
|
2162
|
+
function* entries(object: Record<string, unknown>) {
|
|
2163
|
+
for (const key in object) {
|
|
2164
|
+
if (Object.hasOwn(object, key)) yield [key, object[key]] as const;
|
|
2165
|
+
}
|
|
2166
|
+
}
|
|
2167
|
+
const visit = (root: unknown): void => {
|
|
2168
|
+
const object = record(root);
|
|
2169
|
+
if (!object) {
|
|
2170
|
+
add(root);
|
|
2171
|
+
return;
|
|
2172
|
+
}
|
|
2173
|
+
// Connection inventories are usually flat. Walk the root directly and only
|
|
2174
|
+
// allocate iterator frames when a nested credential container is encountered.
|
|
2175
|
+
for (const key in object) {
|
|
2176
|
+
if (!Object.hasOwn(object, key)) continue;
|
|
2177
|
+
const value = object[key];
|
|
2178
|
+
add(key);
|
|
2179
|
+
if (exhausted) break;
|
|
2180
|
+
const child = record(value);
|
|
2181
|
+
if (!child) {
|
|
2182
|
+
add(value);
|
|
2183
|
+
if (exhausted) break;
|
|
2184
|
+
continue;
|
|
2185
|
+
}
|
|
2186
|
+
const stack = [{ iterator: entries(child), depth: 1 }];
|
|
2187
|
+
while (stack.length && !exhausted) {
|
|
2188
|
+
const frame = stack[stack.length - 1];
|
|
2189
|
+
const entry = frame.iterator.next();
|
|
2190
|
+
if (entry.done) {
|
|
2191
|
+
stack.pop();
|
|
2192
|
+
continue;
|
|
2193
|
+
}
|
|
2194
|
+
const [key, value] = entry.value;
|
|
2195
|
+
add(key);
|
|
2196
|
+
if (exhausted) break;
|
|
2197
|
+
const child = record(value);
|
|
2198
|
+
if (child) {
|
|
2199
|
+
if (frame.depth >= 8) {
|
|
2200
|
+
exhausted = true;
|
|
2201
|
+
break;
|
|
2202
|
+
}
|
|
2203
|
+
stack.push({ iterator: entries(child), depth: frame.depth + 1 });
|
|
2204
|
+
} else add(value);
|
|
2205
|
+
}
|
|
2206
|
+
if (exhausted) break;
|
|
2207
|
+
}
|
|
2208
|
+
};
|
|
2209
|
+
visit(own(own(body, "connection"), "secrets"));
|
|
2210
|
+
if (kind === "auth" && !exhausted) {
|
|
2211
|
+
add(own(own(body, "engine"), "egressLease"));
|
|
2212
|
+
if (!exhausted) visit(own(body, "input"));
|
|
2213
|
+
}
|
|
2214
|
+
return { values, exhausted };
|
|
2215
|
+
}
|
|
2216
|
+
|
|
2042
2217
|
function createRequestScope(input: {
|
|
2043
2218
|
provider: ProviderDefinition;
|
|
2219
|
+
staticSensitiveValues: CompiledDiagnosticSensitiveValues;
|
|
2044
2220
|
kind: "operation" | "auth";
|
|
2045
2221
|
route: string;
|
|
2046
2222
|
requestId?: string;
|
|
@@ -2052,8 +2228,25 @@ function createRequestScope(input: {
|
|
|
2052
2228
|
setHeader?: (name: string, value: string) => void;
|
|
2053
2229
|
declaredErrorCode?: (error: unknown) => OperationErrorCode | undefined;
|
|
2054
2230
|
}): RequestScope {
|
|
2231
|
+
const sensitiveRegistry = createDiagnosticRedactor([], input.staticSensitiveValues);
|
|
2232
|
+
const redact = (text: string) => redactDiagnosticText(text, sensitiveRegistry.redact);
|
|
2233
|
+
bindCriticalDiagnosticRedactor(
|
|
2234
|
+
redact,
|
|
2235
|
+
sensitiveRegistry.redactCritical,
|
|
2236
|
+
sensitiveRegistry.redactStructured,
|
|
2237
|
+
() => sensitiveRegistry.suppressed,
|
|
2238
|
+
);
|
|
2055
2239
|
const requestCost = startRequestCost();
|
|
2056
|
-
const
|
|
2240
|
+
const observeEnv = {
|
|
2241
|
+
observe: createDiagnosticEnvObserver(
|
|
2242
|
+
input.provider,
|
|
2243
|
+
sensitiveRegistry.add,
|
|
2244
|
+
sensitiveRegistry.has,
|
|
2245
|
+
),
|
|
2246
|
+
finished: false,
|
|
2247
|
+
staticValues: input.staticSensitiveValues,
|
|
2248
|
+
};
|
|
2249
|
+
const traceConfig = withDiagnosticEnv(observeEnv, () => resolveTraceConfigFromEnv());
|
|
2057
2250
|
const details = {
|
|
2058
2251
|
route: input.route,
|
|
2059
2252
|
requestId: input.requestId,
|
|
@@ -2072,15 +2265,21 @@ function createRequestScope(input: {
|
|
|
2072
2265
|
const initialTraceId = requestTraceId(input.headers, input.requestId);
|
|
2073
2266
|
const trace: RuntimeTraceContext = traceConfig
|
|
2074
2267
|
? createTraceContext({
|
|
2075
|
-
...
|
|
2268
|
+
...withDiagnosticEnv(observeEnv, () =>
|
|
2269
|
+
resolveServerTraceContextOptions(traceConfig, traceAttributes, undefined, redact),
|
|
2270
|
+
),
|
|
2271
|
+
redact,
|
|
2076
2272
|
...(initialTraceId ? { traceId: initialTraceId } : {}),
|
|
2077
2273
|
})
|
|
2078
|
-
: createTraceContext();
|
|
2274
|
+
: createTraceContext({ redact });
|
|
2275
|
+
bindDiagnosticSensitiveRegistry(trace, sensitiveRegistry);
|
|
2079
2276
|
const proxyCollector = new ProxyTelemetryCollector();
|
|
2080
|
-
const resolverCollector = new ResolverTelemetryCollector();
|
|
2277
|
+
const resolverCollector = new ResolverTelemetryCollector({ redact });
|
|
2278
|
+
const nativeCollector = new NativeTelemetryCollector({ redact });
|
|
2081
2279
|
const telemetry = new RequestTelemetry(trace);
|
|
2082
2280
|
telemetry.register(proxyCollector);
|
|
2083
2281
|
telemetry.register(resolverCollector);
|
|
2282
|
+
telemetry.register(nativeCollector);
|
|
2084
2283
|
let rootRunner: <T>(fn: () => Promise<T>) => Promise<T> = (fn) => fn();
|
|
2085
2284
|
let resolveRoot!: (outcome: RequestTerminalOutcome) => void;
|
|
2086
2285
|
const rootTerminal = new Promise<RequestTerminalOutcome>((resolve) => {
|
|
@@ -2104,12 +2303,14 @@ function createRequestScope(input: {
|
|
|
2104
2303
|
if (outcome.kind === "cancelled") return clientCancelledError();
|
|
2105
2304
|
return undefined;
|
|
2106
2305
|
};
|
|
2107
|
-
const root =
|
|
2108
|
-
|
|
2109
|
-
|
|
2110
|
-
|
|
2111
|
-
|
|
2112
|
-
|
|
2306
|
+
const root = withDiagnosticEnv(observeEnv, () =>
|
|
2307
|
+
trace.span(`request:${input.kind}:${input.route}`, async () => {
|
|
2308
|
+
rootRunner = AsyncLocalStorage.snapshot();
|
|
2309
|
+
const outcome = await rootTerminal;
|
|
2310
|
+
const error = terminalError(outcome);
|
|
2311
|
+
if (error !== undefined) throw error;
|
|
2312
|
+
}),
|
|
2313
|
+
);
|
|
2113
2314
|
void root.catch(() => undefined);
|
|
2114
2315
|
|
|
2115
2316
|
const settleRoot = (): void => {
|
|
@@ -2144,7 +2345,7 @@ function createRequestScope(input: {
|
|
|
2144
2345
|
traceAttributes.route = details.route;
|
|
2145
2346
|
const traceId = requestTraceId(details.headers, details.requestId);
|
|
2146
2347
|
const sanitizedAttributes = Object.fromEntries(
|
|
2147
|
-
Object.entries(sanitizeTraceAttributes(traceAttributes)).map(([key, value]) => [
|
|
2348
|
+
Object.entries(sanitizeTraceAttributes(traceAttributes, redact)).map(([key, value]) => [
|
|
2148
2349
|
key,
|
|
2149
2350
|
String(value),
|
|
2150
2351
|
]),
|
|
@@ -2156,9 +2357,17 @@ function createRequestScope(input: {
|
|
|
2156
2357
|
};
|
|
2157
2358
|
|
|
2158
2359
|
const scope: RequestScope = {
|
|
2360
|
+
redact,
|
|
2159
2361
|
trace,
|
|
2160
2362
|
telemetry,
|
|
2161
2363
|
resolverTelemetry: resolverCollector,
|
|
2364
|
+
nativeTelemetry: nativeCollector,
|
|
2365
|
+
seedCredentials(rawBody, kind): void {
|
|
2366
|
+
const harvested = rawRequestCredentials(rawBody, kind);
|
|
2367
|
+
sensitiveRegistry.add(harvested.values);
|
|
2368
|
+
// An incomplete inventory cannot certify free text: emit less.
|
|
2369
|
+
if (harvested.exhausted) sensitiveRegistry.suppress();
|
|
2370
|
+
},
|
|
2162
2371
|
enrich(enrichment): void {
|
|
2163
2372
|
if (terminalOutcome) return;
|
|
2164
2373
|
if (enrichment.route !== undefined) details.route = enrichment.route;
|
|
@@ -2208,6 +2417,7 @@ function createRequestScope(input: {
|
|
|
2208
2417
|
},
|
|
2209
2418
|
terminalize(outcome): RequestScopeFinishResult {
|
|
2210
2419
|
if (finishedResult) return finishedResult;
|
|
2420
|
+
observeEnv.finished = true;
|
|
2211
2421
|
terminalOutcome = outcome;
|
|
2212
2422
|
const error = terminalError(outcome);
|
|
2213
2423
|
finishedResult = {};
|
|
@@ -2215,8 +2425,7 @@ function createRequestScope(input: {
|
|
|
2215
2425
|
const declaredErrorCode =
|
|
2216
2426
|
error === undefined ? undefined : input.declaredErrorCode?.(error);
|
|
2217
2427
|
const status =
|
|
2218
|
-
outcome.status ??
|
|
2219
|
-
(error === undefined ? 200 : toStatusCode(error, declaredErrorCode));
|
|
2428
|
+
outcome.status ?? (error === undefined ? 200 : toStatusCode(error, declaredErrorCode));
|
|
2220
2429
|
finishedResult = headerSnapshot(error);
|
|
2221
2430
|
const cost = finishRequestCost(requestCost);
|
|
2222
2431
|
try {
|
|
@@ -2231,6 +2440,7 @@ function createRequestScope(input: {
|
|
|
2231
2440
|
cost,
|
|
2232
2441
|
telemetry,
|
|
2233
2442
|
details.correlation,
|
|
2443
|
+
redact,
|
|
2234
2444
|
);
|
|
2235
2445
|
} else {
|
|
2236
2446
|
logProviderError(
|
|
@@ -2246,6 +2456,7 @@ function createRequestScope(input: {
|
|
|
2246
2456
|
telemetry,
|
|
2247
2457
|
finishedResult.errorObservability as ErrorObservabilityDetails,
|
|
2248
2458
|
details.correlation,
|
|
2459
|
+
redact,
|
|
2249
2460
|
);
|
|
2250
2461
|
}
|
|
2251
2462
|
} catch {
|
|
@@ -2281,8 +2492,9 @@ function createRequestScope(input: {
|
|
|
2281
2492
|
return scope;
|
|
2282
2493
|
}
|
|
2283
2494
|
|
|
2284
|
-
// A raw `Response` result skips `toErrorResponse
|
|
2285
|
-
// provider-owned
|
|
2495
|
+
// A raw `Response` result skips `toErrorResponse`. Its payload shape stays
|
|
2496
|
+
// provider-owned; known credentials in error payloads still need redaction.
|
|
2497
|
+
// The observability header is SDK-owned: derive it
|
|
2286
2498
|
// from the status. Only timeouts, rate limits, and 5xx are retryable;
|
|
2287
2499
|
// `isRetryableCategory` would otherwise mark every other 4xx (`upstream_http`)
|
|
2288
2500
|
// as retryable.
|
|
@@ -2297,11 +2509,12 @@ function rawResponseErrorObservability(status: number): ErrorObservabilityDetail
|
|
|
2297
2509
|
// `rawStatusFallback` is decided by the caller from the outcome, not from a
|
|
2298
2510
|
// missing snapshot: a failed outcome whose thrown value is `undefined` also has
|
|
2299
2511
|
// no `errorObservability`, and its 500 carries the SDK envelope, not a raw body.
|
|
2300
|
-
function responseWithRequestScopeHeaders(
|
|
2512
|
+
async function responseWithRequestScopeHeaders(
|
|
2301
2513
|
response: Response,
|
|
2302
2514
|
finished: RequestScopeFinishResult,
|
|
2303
2515
|
rawStatusFallback: boolean,
|
|
2304
|
-
|
|
2516
|
+
redact: DiagnosticRedactor,
|
|
2517
|
+
): Promise<Response> {
|
|
2305
2518
|
const headers = new Headers(response.headers);
|
|
2306
2519
|
headers.delete(PROVIDER_TELEMETRY_HEADER);
|
|
2307
2520
|
if (finished.providerTelemetryHeader) {
|
|
@@ -2316,24 +2529,36 @@ function responseWithRequestScopeHeaders(
|
|
|
2316
2529
|
if (errorObservability) {
|
|
2317
2530
|
headers.set(ERROR_OBSERVABILITY_HEADER, JSON.stringify(errorObservability));
|
|
2318
2531
|
}
|
|
2319
|
-
|
|
2532
|
+
// Raw Response bodies are provider-owned. Preserve their stream and representation.
|
|
2533
|
+
const body = response.body;
|
|
2534
|
+
const statusText =
|
|
2535
|
+
rawStatusFallback && response.status >= 400
|
|
2536
|
+
? redactDiagnosticText(response.statusText, redact)
|
|
2537
|
+
: response.statusText;
|
|
2538
|
+
return new Response(body, {
|
|
2320
2539
|
headers,
|
|
2321
2540
|
status: response.status,
|
|
2322
|
-
|
|
2541
|
+
// When free text cannot be certified, use the SDK's standard HTTP reason
|
|
2542
|
+
// phrase. It preserves the status contract without trusting provider text.
|
|
2543
|
+
statusText:
|
|
2544
|
+
statusText === REDACTION_FAILED && isDiagnosticRedactionSuppressed(redact)
|
|
2545
|
+
? (STATUS_CODES[response.status] ?? "")
|
|
2546
|
+
: statusText,
|
|
2323
2547
|
});
|
|
2324
2548
|
}
|
|
2325
2549
|
|
|
2326
|
-
function finalizeRequestResponse(
|
|
2550
|
+
async function finalizeRequestResponse(
|
|
2327
2551
|
scope: RequestScope,
|
|
2328
2552
|
response: Response,
|
|
2329
2553
|
outcome: RequestTerminalOutcome,
|
|
2330
|
-
): Response {
|
|
2554
|
+
): Promise<Response> {
|
|
2331
2555
|
try {
|
|
2332
2556
|
const error = outcome.kind === "failed" ? outcome.error : undefined;
|
|
2333
|
-
const finalResponse = responseWithRequestScopeHeaders(
|
|
2557
|
+
const finalResponse = await responseWithRequestScopeHeaders(
|
|
2334
2558
|
response,
|
|
2335
2559
|
scope.snapshotHeaders(error),
|
|
2336
2560
|
outcome.kind === "completed",
|
|
2561
|
+
scope.redact,
|
|
2337
2562
|
);
|
|
2338
2563
|
scope.terminalize(outcome);
|
|
2339
2564
|
return finalResponse;
|
|
@@ -2552,11 +2777,7 @@ function toSseResponse(
|
|
|
2552
2777
|
const validated = await validateSseEvent(operation, next.value);
|
|
2553
2778
|
const encodedEvent = encodeSseEvent(validated);
|
|
2554
2779
|
const bytes = encoder.encode(encodedEvent);
|
|
2555
|
-
assertStreamPayloadWithinLimit(
|
|
2556
|
-
bytes.byteLength,
|
|
2557
|
-
transport?.maxEventBytes,
|
|
2558
|
-
"event",
|
|
2559
|
-
);
|
|
2780
|
+
assertStreamPayloadWithinLimit(bytes.byteLength, transport?.maxEventBytes, "event");
|
|
2560
2781
|
return bytes;
|
|
2561
2782
|
});
|
|
2562
2783
|
controller.enqueue(encodedBytes);
|
|
@@ -2565,9 +2786,13 @@ function toSseResponse(
|
|
|
2565
2786
|
controller.enqueue(
|
|
2566
2787
|
encoder.encode(
|
|
2567
2788
|
encodeSseEvent(
|
|
2568
|
-
streamError(
|
|
2569
|
-
|
|
2570
|
-
|
|
2789
|
+
streamError(
|
|
2790
|
+
"stream_error",
|
|
2791
|
+
sanitizeDiagnosticText(redactDiagnosticText(message, lifecycle.redact)),
|
|
2792
|
+
{
|
|
2793
|
+
...(requestId ? { requestId } : {}),
|
|
2794
|
+
},
|
|
2795
|
+
),
|
|
2571
2796
|
),
|
|
2572
2797
|
),
|
|
2573
2798
|
);
|
|
@@ -2810,6 +3035,7 @@ async function handleOperation(
|
|
|
2810
3035
|
request.requestId,
|
|
2811
3036
|
"stealth",
|
|
2812
3037
|
error,
|
|
3038
|
+
scope.redact,
|
|
2813
3039
|
);
|
|
2814
3040
|
}
|
|
2815
3041
|
}
|
|
@@ -2825,11 +3051,13 @@ async function handleOperation(
|
|
|
2825
3051
|
request.requestId,
|
|
2826
3052
|
"browser",
|
|
2827
3053
|
error,
|
|
3054
|
+
scope.redact,
|
|
2828
3055
|
);
|
|
2829
3056
|
}
|
|
2830
3057
|
}
|
|
2831
3058
|
};
|
|
2832
3059
|
const streamLifecycle: RequestStreamLifecycle = {
|
|
3060
|
+
redact: scope.redact,
|
|
2833
3061
|
runStep<T>(fn: () => Promise<T>): Promise<T> {
|
|
2834
3062
|
return scope.runStreamStep(fn);
|
|
2835
3063
|
},
|
|
@@ -2953,6 +3181,7 @@ async function handleAuthFlow(
|
|
|
2953
3181
|
request.requestId,
|
|
2954
3182
|
"stealth",
|
|
2955
3183
|
error,
|
|
3184
|
+
scope.redact,
|
|
2956
3185
|
);
|
|
2957
3186
|
}
|
|
2958
3187
|
}
|
|
@@ -3074,12 +3303,15 @@ function operationRequestFromForwardingEnvelope(
|
|
|
3074
3303
|
};
|
|
3075
3304
|
}
|
|
3076
3305
|
|
|
3077
|
-
function parseStatefulForwardingEnvelope(
|
|
3306
|
+
function parseStatefulForwardingEnvelope(
|
|
3307
|
+
rawBody: unknown,
|
|
3308
|
+
redact: DiagnosticRedactor,
|
|
3309
|
+
): ProviderServerStatefulForwardEnvelope {
|
|
3078
3310
|
const parsed = ProviderServerStatefulForwardEnvelopeSchema.safeParse(rawBody);
|
|
3079
3311
|
if (parsed.success) return parsed.data;
|
|
3080
3312
|
throw new ProviderError("Stateful forwarding envelope is invalid.", {
|
|
3081
3313
|
code: "STATEFUL_FORWARDING_ENVELOPE_INVALID",
|
|
3082
|
-
details: zodDetails(parsed.error),
|
|
3314
|
+
details: zodDetails(parsed.error, redact),
|
|
3083
3315
|
});
|
|
3084
3316
|
}
|
|
3085
3317
|
|
|
@@ -3087,7 +3319,9 @@ function parseStatefulForwardingEnvelope(rawBody: unknown): ProviderServerStatef
|
|
|
3087
3319
|
* Primary, cross-runtime app factory. Declared capability ESM is preloaded
|
|
3088
3320
|
* asynchronously, so this path works on Bun and every supported Node release.
|
|
3089
3321
|
*/
|
|
3090
|
-
export async function createServerAppAsync<
|
|
3322
|
+
export async function createServerAppAsync<
|
|
3323
|
+
TContext extends Partial<ProviderContext> = ProviderContext,
|
|
3324
|
+
>(
|
|
3091
3325
|
provider: ProviderDefinition<TContext>,
|
|
3092
3326
|
options: ProviderServerOptions<TContext> = {},
|
|
3093
3327
|
): Promise<Hono> {
|
|
@@ -3134,6 +3368,12 @@ function createServerAppWithCapabilityModules(
|
|
|
3134
3368
|
engine: serverOptions.engine ?? createInProcessProviderEngine(),
|
|
3135
3369
|
};
|
|
3136
3370
|
const app = new Hono();
|
|
3371
|
+
// Compile the startup inventory once, composed with the shared outside-context fallback.
|
|
3372
|
+
const staticSensitiveValues = compileProcessDiagnosticSensitiveValues(
|
|
3373
|
+
collectStaticDiagnosticSensitiveValues(provider, {
|
|
3374
|
+
statefulForwardingSecret: options.statefulForwarding?.secret,
|
|
3375
|
+
}),
|
|
3376
|
+
);
|
|
3137
3377
|
const logger = options.logger ?? defaultProviderServerLogger;
|
|
3138
3378
|
const operationErrorCodes = buildOperationErrorCodeLookup(provider);
|
|
3139
3379
|
const statefulForwardingReplayCache = new StatefulForwardingReplayCache(
|
|
@@ -3189,6 +3429,7 @@ function createServerAppWithCapabilityModules(
|
|
|
3189
3429
|
const operation = "stateful-internal";
|
|
3190
3430
|
const requestScope = createRequestScope({
|
|
3191
3431
|
provider,
|
|
3432
|
+
staticSensitiveValues,
|
|
3192
3433
|
kind: "operation",
|
|
3193
3434
|
route: operation,
|
|
3194
3435
|
headers: Object.fromEntries(c.req.raw.headers.entries()),
|
|
@@ -3218,7 +3459,8 @@ function createServerAppWithCapabilityModules(
|
|
|
3218
3459
|
code: "STATEFUL_FORWARDING_ENVELOPE_INVALID",
|
|
3219
3460
|
});
|
|
3220
3461
|
}
|
|
3221
|
-
|
|
3462
|
+
requestScope.seedCredentials(rawBody, "stateful");
|
|
3463
|
+
const envelope = parseStatefulForwardingEnvelope(rawBody, requestScope.redact);
|
|
3222
3464
|
if (envelope.providerId !== provider.id) {
|
|
3223
3465
|
throw new ProviderError(
|
|
3224
3466
|
"Stateful forwarding envelope providerId does not match the served provider.",
|
|
@@ -3354,7 +3596,10 @@ function createServerAppWithCapabilityModules(
|
|
|
3354
3596
|
...(requestId ? { requestId } : {}),
|
|
3355
3597
|
});
|
|
3356
3598
|
const observabilityDetails = errorObservabilityDetails(error, declaredErrorCode);
|
|
3357
|
-
const response = c.json(
|
|
3599
|
+
const response = c.json(
|
|
3600
|
+
toErrorResponse(error, requestId, observabilityDetails, requestScope.redact),
|
|
3601
|
+
status,
|
|
3602
|
+
);
|
|
3358
3603
|
return finalizeRequestResponse(requestScope, response, {
|
|
3359
3604
|
kind: "failed",
|
|
3360
3605
|
status,
|
|
@@ -3368,6 +3613,7 @@ function createServerAppWithCapabilityModules(
|
|
|
3368
3613
|
const operation = c.req.param("operation");
|
|
3369
3614
|
const requestScope = createRequestScope({
|
|
3370
3615
|
provider,
|
|
3616
|
+
staticSensitiveValues,
|
|
3371
3617
|
kind: "operation",
|
|
3372
3618
|
route: operation,
|
|
3373
3619
|
operationId: operation,
|
|
@@ -3381,6 +3627,7 @@ function createServerAppWithCapabilityModules(
|
|
|
3381
3627
|
.clone()
|
|
3382
3628
|
.json()
|
|
3383
3629
|
.catch(() => undefined);
|
|
3630
|
+
requestScope.seedCredentials(rawBody, "operation");
|
|
3384
3631
|
const body = OperationRequestSchema.parse(rawBody);
|
|
3385
3632
|
const requestHeaders = Object.fromEntries(c.req.raw.headers.entries());
|
|
3386
3633
|
body.headers = { ...requestHeaders, ...body.headers };
|
|
@@ -3405,7 +3652,12 @@ function createServerAppWithCapabilityModules(
|
|
|
3405
3652
|
);
|
|
3406
3653
|
const response = handled instanceof Response ? handled : c.json(handled);
|
|
3407
3654
|
return streaming
|
|
3408
|
-
? responseWithRequestScopeHeaders(
|
|
3655
|
+
? responseWithRequestScopeHeaders(
|
|
3656
|
+
response,
|
|
3657
|
+
requestScope.snapshotHeaders(),
|
|
3658
|
+
true,
|
|
3659
|
+
requestScope.redact,
|
|
3660
|
+
)
|
|
3409
3661
|
: response;
|
|
3410
3662
|
};
|
|
3411
3663
|
const response = streaming
|
|
@@ -3422,7 +3674,10 @@ function createServerAppWithCapabilityModules(
|
|
|
3422
3674
|
const requestId = extractRequestId(rawBody);
|
|
3423
3675
|
requestScope.enrich({ ...(requestId ? { requestId } : {}) });
|
|
3424
3676
|
const observabilityDetails = errorObservabilityDetails(error, declaredErrorCode);
|
|
3425
|
-
const response = c.json(
|
|
3677
|
+
const response = c.json(
|
|
3678
|
+
toErrorResponse(error, requestId, observabilityDetails, requestScope.redact),
|
|
3679
|
+
status,
|
|
3680
|
+
);
|
|
3426
3681
|
return finalizeRequestResponse(requestScope, response, {
|
|
3427
3682
|
kind: "failed",
|
|
3428
3683
|
status,
|
|
@@ -3448,6 +3703,7 @@ function createServerAppWithCapabilityModules(
|
|
|
3448
3703
|
let rawBody: unknown;
|
|
3449
3704
|
const requestScope = createRequestScope({
|
|
3450
3705
|
provider,
|
|
3706
|
+
staticSensitiveValues,
|
|
3451
3707
|
kind: "auth",
|
|
3452
3708
|
route: logRoute,
|
|
3453
3709
|
headers: Object.fromEntries(c.req.raw.headers.entries()),
|
|
@@ -3459,6 +3715,7 @@ function createServerAppWithCapabilityModules(
|
|
|
3459
3715
|
.clone()
|
|
3460
3716
|
.json()
|
|
3461
3717
|
.catch(() => undefined);
|
|
3718
|
+
requestScope.seedCredentials(rawBody, "auth");
|
|
3462
3719
|
const body = withAuthRequestHeaders(
|
|
3463
3720
|
AuthFlowRequestSchema.parse(rawBody),
|
|
3464
3721
|
c.req.raw.headers,
|
|
@@ -3498,7 +3755,10 @@ function createServerAppWithCapabilityModules(
|
|
|
3498
3755
|
const requestId = extractRequestId(rawBody);
|
|
3499
3756
|
requestScope.enrich({ ...(requestId ? { requestId } : {}) });
|
|
3500
3757
|
const observabilityDetails = errorObservabilityDetails(error);
|
|
3501
|
-
const response = c.json(
|
|
3758
|
+
const response = c.json(
|
|
3759
|
+
toErrorResponse(error, requestId, observabilityDetails, requestScope.redact),
|
|
3760
|
+
status,
|
|
3761
|
+
);
|
|
3502
3762
|
return finalizeRequestResponse(requestScope, response, {
|
|
3503
3763
|
kind: "failed",
|
|
3504
3764
|
status,
|