@qlever-llc/trellis 0.10.10 → 0.10.12
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/client.d.ts +2 -0
- package/esm/client.d.ts.map +1 -1
- package/esm/client.js +2 -0
- package/esm/client_connect.d.ts +3 -2
- package/esm/client_connect.d.ts.map +1 -1
- package/esm/client_connect.js +4 -1
- package/esm/errors/TrellisError.d.ts +3 -3
- package/esm/errors/TrellisError.js +3 -3
- package/esm/server/health.d.ts.map +1 -1
- package/esm/server/health.js +34 -3
- package/esm/server/internal_jobs/job-manager.d.ts.map +1 -1
- package/esm/server/internal_jobs/job-manager.js +32 -1
- package/esm/server/runtime.d.ts +3 -0
- package/esm/server/runtime.d.ts.map +1 -1
- package/esm/server/service.d.ts +15 -0
- package/esm/server/service.d.ts.map +1 -1
- package/esm/server/service.js +41 -3
- package/esm/server.d.ts.map +1 -1
- package/esm/server.js +99 -10
- package/esm/service/deno.d.ts +1 -1
- package/esm/service/deno.d.ts.map +1 -1
- package/esm/service/mod.d.ts +1 -1
- package/esm/service/mod.d.ts.map +1 -1
- package/esm/service/node.d.ts +1 -1
- package/esm/service/node.d.ts.map +1 -1
- package/esm/service/outbox_inbox.d.ts.map +1 -1
- package/esm/service/outbox_inbox.js +14 -0
- package/esm/telemetry/core.d.ts.map +1 -1
- package/esm/telemetry/core.js +1 -1
- package/esm/telemetry/env.d.ts.map +1 -1
- package/esm/telemetry/env.js +6 -1
- package/esm/telemetry/init.d.ts +3 -0
- package/esm/telemetry/init.d.ts.map +1 -0
- package/esm/telemetry/init.js +7 -0
- package/esm/telemetry/metrics.d.ts +34 -0
- package/esm/telemetry/metrics.d.ts.map +1 -0
- package/esm/telemetry/metrics.js +181 -0
- package/esm/telemetry/mod.d.ts +3 -0
- package/esm/telemetry/mod.d.ts.map +1 -1
- package/esm/telemetry/mod.js +2 -0
- package/esm/telemetry/runtime.d.ts +2 -0
- package/esm/telemetry/runtime.d.ts.map +1 -0
- package/esm/telemetry/runtime.js +134 -0
- package/esm/telemetry.d.ts +3 -0
- package/esm/telemetry.d.ts.map +1 -0
- package/esm/telemetry.js +2 -0
- package/esm/transfer.d.ts.map +1 -1
- package/esm/transfer.js +27 -16
- package/esm/trellis.d.ts +28 -4
- package/esm/trellis.d.ts.map +1 -1
- package/esm/trellis.js +575 -80
- package/package.json +7 -5
- package/script/client.d.ts +2 -0
- package/script/client.d.ts.map +1 -1
- package/script/client.js +2 -0
- package/script/client_connect.d.ts +3 -2
- package/script/client_connect.d.ts.map +1 -1
- package/script/client_connect.js +4 -1
- package/script/errors/TrellisError.d.ts +3 -3
- package/script/errors/TrellisError.js +3 -3
- package/script/server/health.d.ts.map +1 -1
- package/script/server/health.js +34 -3
- package/script/server/internal_jobs/job-manager.d.ts.map +1 -1
- package/script/server/internal_jobs/job-manager.js +32 -1
- package/script/server/runtime.d.ts +3 -0
- package/script/server/runtime.d.ts.map +1 -1
- package/script/server/service.d.ts +15 -0
- package/script/server/service.d.ts.map +1 -1
- package/script/server/service.js +40 -2
- package/script/server.d.ts.map +1 -1
- package/script/server.js +98 -9
- package/script/service/deno.d.ts +1 -1
- package/script/service/deno.d.ts.map +1 -1
- package/script/service/mod.d.ts +1 -1
- package/script/service/mod.d.ts.map +1 -1
- package/script/service/node.d.ts +1 -1
- package/script/service/node.d.ts.map +1 -1
- package/script/service/outbox_inbox.d.ts.map +1 -1
- package/script/service/outbox_inbox.js +14 -0
- package/script/telemetry/core.d.ts.map +1 -1
- package/script/telemetry/core.js +1 -1
- package/script/telemetry/env.d.ts.map +1 -1
- package/script/telemetry/env.js +6 -1
- package/script/telemetry/init.d.ts +3 -0
- package/script/telemetry/init.d.ts.map +1 -0
- package/script/telemetry/init.js +10 -0
- package/script/telemetry/metrics.d.ts +34 -0
- package/script/telemetry/metrics.d.ts.map +1 -0
- package/script/telemetry/metrics.js +186 -0
- package/script/telemetry/mod.d.ts +3 -0
- package/script/telemetry/mod.d.ts.map +1 -1
- package/script/telemetry/mod.js +7 -1
- package/script/telemetry/runtime.d.ts +2 -0
- package/script/telemetry/runtime.d.ts.map +1 -0
- package/script/telemetry/runtime.js +137 -0
- package/script/telemetry.d.ts +3 -0
- package/script/telemetry.d.ts.map +1 -0
- package/script/telemetry.js +18 -0
- package/script/transfer.d.ts.map +1 -1
- package/script/transfer.js +28 -17
- package/script/trellis.d.ts +28 -4
- package/script/trellis.d.ts.map +1 -1
- package/script/trellis.js +606 -110
- package/src/client.ts +4 -0
- package/src/client_connect.ts +11 -9
- package/src/errors/TrellisError.ts +4 -4
- package/src/server/health.ts +41 -3
- package/src/server/internal_jobs/job-manager.ts +35 -5
- package/src/server/runtime.ts +4 -0
- package/src/server/service.ts +75 -3
- package/src/server.ts +124 -14
- package/src/service/deno.ts +1 -0
- package/src/service/mod.ts +1 -0
- package/src/service/node.ts +1 -0
- package/src/service/outbox_inbox.ts +14 -0
- package/src/telemetry/core.ts +1 -1
- package/src/telemetry/env.ts +5 -1
- package/src/telemetry/init.ts +8 -0
- package/src/telemetry/metrics.ts +294 -0
- package/src/telemetry/mod.ts +7 -0
- package/src/telemetry/runtime.ts +218 -0
- package/src/telemetry.ts +2 -0
- package/src/transfer.ts +69 -30
- package/src/trellis.ts +652 -141
- package/esm/tracing.d.ts +0 -5
- package/esm/tracing.d.ts.map +0 -1
- package/esm/tracing.js +0 -8
- package/script/tracing.d.ts +0 -5
- package/script/tracing.d.ts.map +0 -1
- package/script/tracing.js +0 -27
- package/src/tracing.ts +0 -28
package/script/trellis.js
CHANGED
|
@@ -10,7 +10,7 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
|
|
|
10
10
|
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
11
11
|
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
12
12
|
};
|
|
13
|
-
var _Trellis_instances, _Trellis_log, _Trellis_tasks, _Trellis_hasExplicitApi, _Trellis_noResponderMaxRetries, _Trellis_noResponderRetryMs, _Trellis_onSessionNotFound, _Trellis_operationStore, _Trellis_eventConsumers, _Trellis_durableEventLoops, _Trellis_createStateFacade, _Trellis_createRpcFacade, _Trellis_createRpcHandleFacade, _Trellis_createEventFacade, _Trellis_createEventPublishFacade, _Trellis_createFeedFacade, _Trellis_createHandlerTrellis, _Trellis_createOperationFacade, _Trellis_unknownApiError, _Trellis_requestBuiltRpcUnknown, _Trellis_requestBuiltRpc, _Trellis_handleBrowserAuthRequired, _Trellis_authenticateFeedRequest, _Trellis_subscribeFeed, _Trellis_handleFeed, _Trellis_processFeedMessage, _Trellis_handleRPC, _Trellis_processRPCMessage, _Trellis_respondWithPayload, _Trellis_respondWithError, _Trellis_startEphemeralEvent, _Trellis_resolveEventConsumerGroup, _Trellis_registerDurableEventHandler, _Trellis_startDurableEventConsumer, _Trellis_durableEventConsumerGroupReady, _Trellis_runDurableEventConsumer, _Trellis_handleDurableEvent, _Trellis_handleDurableEventConsumer, _Trellis_parseEventMessage, _Trellis_escapeSubjectToken, _Trellis_currentIat, _Trellis_createProof, _Trellis_requestMessageWithRetry, _Trellis_requestJson, _Trellis_watchJson;
|
|
13
|
+
var _Trellis_instances, _Trellis_log, _Trellis_tasks, _Trellis_hasExplicitApi, _Trellis_noResponderMaxRetries, _Trellis_noResponderRetryMs, _Trellis_onSessionNotFound, _Trellis_operationStore, _Trellis_eventConsumers, _Trellis_durableEventLoops, _Trellis_createStateFacade, _Trellis_createRpcFacade, _Trellis_createRpcHandleFacade, _Trellis_createEventFacade, _Trellis_createEventPublishFacade, _Trellis_createFeedFacade, _Trellis_createHandlerTrellis, _Trellis_createOperationFacade, _Trellis_unknownApiError, _Trellis_requestBuiltRpcUnknown, _Trellis_requestBuiltRpc, _Trellis_handleBrowserAuthRequired, _Trellis_authenticateFeedRequest, _Trellis_subscribeFeed, _Trellis_handleFeed, _Trellis_processFeedMessage, _Trellis_handleRPC, _Trellis_processRPCMessage, _Trellis_respondWithPayload, _Trellis_respondWithError, _Trellis_startEphemeralEvent, _Trellis_invokeEventHandler, _Trellis_resolveEventConsumerGroup, _Trellis_registerDurableEventHandler, _Trellis_startDurableEventConsumer, _Trellis_durableEventConsumerGroupReady, _Trellis_runDurableEventConsumer, _Trellis_handleDurableEvent, _Trellis_handleDurableEventConsumer, _Trellis_parseEventMessage, _Trellis_escapeSubjectToken, _Trellis_currentIat, _Trellis_createProof, _Trellis_requestMessageWithRetry, _Trellis_requestJson, _Trellis_watchJson;
|
|
14
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
15
|
exports.Trellis = exports.DurableOperationRecordSchema = void 0;
|
|
16
16
|
exports.safeJson = safeJson;
|
|
@@ -21,6 +21,7 @@ exports.sha256 = sha256;
|
|
|
21
21
|
exports.buildProofInput = buildProofInput;
|
|
22
22
|
exports.isOperationDeferred = isOperationDeferred;
|
|
23
23
|
exports.isResultLike = isResultLike;
|
|
24
|
+
exports.annotateHandlerBoundaryError = annotateHandlerBoundaryError;
|
|
24
25
|
exports.buildRuntimeOperationSnapshot = buildRuntimeOperationSnapshot;
|
|
25
26
|
exports.isTerminalRuntimeOperationSnapshot = isTerminalRuntimeOperationSnapshot;
|
|
26
27
|
exports.createTrellisInternal = createTrellisInternal;
|
|
@@ -28,7 +29,7 @@ const jetstream_1 = require("@nats-io/jetstream");
|
|
|
28
29
|
const nats_core_1 = require("@nats-io/nats-core");
|
|
29
30
|
const mod_js_1 = require("./contract_support/mod.js");
|
|
30
31
|
const result_1 = require("@qlever-llc/result");
|
|
31
|
-
const
|
|
32
|
+
const mod_js_2 = require("./telemetry/mod.js");
|
|
32
33
|
const typebox_1 = require("typebox");
|
|
33
34
|
const value_1 = require("typebox/value");
|
|
34
35
|
const ulid_1 = require("ulid");
|
|
@@ -204,6 +205,27 @@ function isOperationDeferred(value) {
|
|
|
204
205
|
function isResultLike(value) {
|
|
205
206
|
return value instanceof result_1.Result;
|
|
206
207
|
}
|
|
208
|
+
function compactHandlerErrorContext(context) {
|
|
209
|
+
return Object.fromEntries(Object.entries(context).filter(([key, value]) => key !== "traceId" && value !== undefined));
|
|
210
|
+
}
|
|
211
|
+
function sanitizeHandlerErrorContext(error) {
|
|
212
|
+
delete error.getContext().subject;
|
|
213
|
+
}
|
|
214
|
+
function annotateHandlerBoundaryError(cause, context) {
|
|
215
|
+
const error = cause instanceof result_1.BaseError && !(cause instanceof RemoteError_js_1.RemoteError)
|
|
216
|
+
? cause
|
|
217
|
+
: new index_js_1.UnexpectedError({ cause });
|
|
218
|
+
sanitizeHandlerErrorContext(error);
|
|
219
|
+
error.withContext(compactHandlerErrorContext(context));
|
|
220
|
+
error.withTraceId(context.traceId);
|
|
221
|
+
return error;
|
|
222
|
+
}
|
|
223
|
+
function recordRuntimeError(error, attributes) {
|
|
224
|
+
(0, mod_js_2.recordTrellisError)(error, {
|
|
225
|
+
messagingSystem: "nats",
|
|
226
|
+
...attributes,
|
|
227
|
+
});
|
|
228
|
+
}
|
|
207
229
|
const DurableOperationSignalSchema = typebox_1.Type.Object({
|
|
208
230
|
operationId: typebox_1.Type.String(),
|
|
209
231
|
sequence: typebox_1.Type.Number(),
|
|
@@ -234,8 +256,11 @@ const DurableOperationSnapshotSchema = typebox_1.Type.Object({
|
|
|
234
256
|
})),
|
|
235
257
|
output: typebox_1.Type.Optional(typebox_1.Type.Any()),
|
|
236
258
|
error: typebox_1.Type.Optional(typebox_1.Type.Object({
|
|
259
|
+
id: typebox_1.Type.Optional(typebox_1.Type.String()),
|
|
237
260
|
type: typebox_1.Type.String(),
|
|
238
261
|
message: typebox_1.Type.String(),
|
|
262
|
+
context: typebox_1.Type.Optional(typebox_1.Type.Record(typebox_1.Type.String(), typebox_1.Type.Unknown())),
|
|
263
|
+
traceId: typebox_1.Type.Optional(typebox_1.Type.String()),
|
|
239
264
|
})),
|
|
240
265
|
});
|
|
241
266
|
exports.DurableOperationRecordSchema = typebox_1.Type.Object({
|
|
@@ -741,6 +766,18 @@ class Trellis {
|
|
|
741
766
|
writable: true,
|
|
742
767
|
value: void 0
|
|
743
768
|
});
|
|
769
|
+
Object.defineProperty(this, "contractId", {
|
|
770
|
+
enumerable: true,
|
|
771
|
+
configurable: true,
|
|
772
|
+
writable: true,
|
|
773
|
+
value: void 0
|
|
774
|
+
});
|
|
775
|
+
Object.defineProperty(this, "contractDigest", {
|
|
776
|
+
enumerable: true,
|
|
777
|
+
configurable: true,
|
|
778
|
+
writable: true,
|
|
779
|
+
value: void 0
|
|
780
|
+
});
|
|
744
781
|
Object.defineProperty(this, "nats", {
|
|
745
782
|
enumerable: true,
|
|
746
783
|
configurable: true,
|
|
@@ -783,6 +820,8 @@ class Trellis {
|
|
|
783
820
|
__classPrivateFieldSet(this, _Trellis_log, (opts?.log ?? globals_js_1.logger).child({ lib: "trellis" }), "f");
|
|
784
821
|
this.timeout = opts?.timeout ?? 3000;
|
|
785
822
|
this.stream = opts?.stream ?? "trellis";
|
|
823
|
+
this.contractId = opts?.contractId;
|
|
824
|
+
this.contractDigest = opts?.contractDigest;
|
|
786
825
|
__classPrivateFieldSet(this, _Trellis_hasExplicitApi, api !== undefined, "f");
|
|
787
826
|
__classPrivateFieldSet(this, _Trellis_noResponderMaxRetries, opts?.noResponderRetry?.maxAttempts ??
|
|
788
827
|
DEFAULT_NO_RESPONDER_MAX_RETRIES, "f");
|
|
@@ -917,14 +956,27 @@ class Trellis {
|
|
|
917
956
|
const eventName = event;
|
|
918
957
|
const ctx = this.api["events"][eventName];
|
|
919
958
|
if (!ctx) {
|
|
920
|
-
|
|
959
|
+
const error = new index_js_1.UnexpectedError({
|
|
921
960
|
cause: __classPrivateFieldGet(this, _Trellis_instances, "m", _Trellis_unknownApiError).call(this, "event", event.toString()),
|
|
922
961
|
context: { event: event.toString() },
|
|
923
|
-
})
|
|
962
|
+
});
|
|
963
|
+
recordRuntimeError(error, {
|
|
964
|
+
surface: "event",
|
|
965
|
+
direction: "publisher",
|
|
966
|
+
operation: event,
|
|
967
|
+
phase: "prepare",
|
|
968
|
+
});
|
|
969
|
+
return (0, result_1.err)(error);
|
|
924
970
|
}
|
|
925
971
|
const subject = this.template(ctx.subject, data).take();
|
|
926
972
|
if ((0, result_1.isErr)(subject)) {
|
|
927
973
|
globals_js_1.logger.error({ err: subject.error }, "Failed to template event.");
|
|
974
|
+
recordRuntimeError(subject.error, {
|
|
975
|
+
surface: "event",
|
|
976
|
+
direction: "publisher",
|
|
977
|
+
operation: event,
|
|
978
|
+
phase: "request_encoding",
|
|
979
|
+
});
|
|
928
980
|
return subject;
|
|
929
981
|
}
|
|
930
982
|
const header = {
|
|
@@ -938,11 +990,18 @@ class Trellis {
|
|
|
938
990
|
const msg = (0, codec_js_1.encodeSchema)(ctx.event, payload).take();
|
|
939
991
|
if ((0, result_1.isErr)(msg)) {
|
|
940
992
|
globals_js_1.logger.error({ err: msg.error }, "Failed to encode event.");
|
|
941
|
-
|
|
993
|
+
const error = new index_js_1.UnexpectedError({ cause: msg.error });
|
|
994
|
+
recordRuntimeError(error, {
|
|
995
|
+
surface: "event",
|
|
996
|
+
direction: "publisher",
|
|
997
|
+
operation: event,
|
|
998
|
+
phase: "request_encoding",
|
|
999
|
+
});
|
|
1000
|
+
return (0, result_1.err)(error);
|
|
942
1001
|
}
|
|
943
1002
|
const headers = (0, nats_core_1.headers)();
|
|
944
1003
|
headers.set("Nats-Msg-Id", header.id);
|
|
945
|
-
(0,
|
|
1004
|
+
(0, mod_js_2.injectTraceContext)((0, mod_js_2.createNatsHeaderCarrier)(headers));
|
|
946
1005
|
const headerRecord = {};
|
|
947
1006
|
for (const [key, value] of headers) {
|
|
948
1007
|
headerRecord[key] = value.join(",");
|
|
@@ -956,7 +1015,17 @@ class Trellis {
|
|
|
956
1015
|
}));
|
|
957
1016
|
}
|
|
958
1017
|
catch (cause) {
|
|
959
|
-
|
|
1018
|
+
const error = new index_js_1.UnexpectedError({
|
|
1019
|
+
cause,
|
|
1020
|
+
context: { event: event.toString() },
|
|
1021
|
+
});
|
|
1022
|
+
recordRuntimeError(error, {
|
|
1023
|
+
surface: "event",
|
|
1024
|
+
direction: "publisher",
|
|
1025
|
+
operation: event,
|
|
1026
|
+
phase: "prepare",
|
|
1027
|
+
});
|
|
1028
|
+
return (0, result_1.err)(error);
|
|
960
1029
|
}
|
|
961
1030
|
}
|
|
962
1031
|
/**
|
|
@@ -975,7 +1044,17 @@ class Trellis {
|
|
|
975
1044
|
return (0, result_1.ok)(undefined);
|
|
976
1045
|
}
|
|
977
1046
|
catch (cause) {
|
|
978
|
-
|
|
1047
|
+
const error = new index_js_1.UnexpectedError({
|
|
1048
|
+
cause,
|
|
1049
|
+
context: { event: event.event },
|
|
1050
|
+
});
|
|
1051
|
+
recordRuntimeError(error, {
|
|
1052
|
+
surface: "event",
|
|
1053
|
+
direction: "publisher",
|
|
1054
|
+
operation: event.event,
|
|
1055
|
+
phase: "publish",
|
|
1056
|
+
});
|
|
1057
|
+
return (0, result_1.err)(error);
|
|
979
1058
|
}
|
|
980
1059
|
})());
|
|
981
1060
|
}
|
|
@@ -1212,13 +1291,25 @@ _Trellis_log = new WeakMap(), _Trellis_tasks = new WeakMap(), _Trellis_hasExplic
|
|
|
1212
1291
|
__classPrivateFieldGet(this, _Trellis_log, "f").trace({ method: String(method) }, `Calling ${method.toString()}.`);
|
|
1213
1292
|
const msg = encodeRuntimeSchema(ctx.input, input).take();
|
|
1214
1293
|
if ((0, result_1.isErr)(msg)) {
|
|
1294
|
+
recordRuntimeError(msg.error, {
|
|
1295
|
+
surface: "rpc",
|
|
1296
|
+
direction: "client",
|
|
1297
|
+
operation: method,
|
|
1298
|
+
phase: "request_encoding",
|
|
1299
|
+
});
|
|
1215
1300
|
return msg;
|
|
1216
1301
|
}
|
|
1217
1302
|
const subject = this.template(ctx.subject, input).take();
|
|
1218
1303
|
if ((0, result_1.isErr)(subject)) {
|
|
1304
|
+
recordRuntimeError(subject.error, {
|
|
1305
|
+
surface: "rpc",
|
|
1306
|
+
direction: "client",
|
|
1307
|
+
operation: method,
|
|
1308
|
+
phase: "request_encoding",
|
|
1309
|
+
});
|
|
1219
1310
|
return subject;
|
|
1220
1311
|
}
|
|
1221
|
-
const span = (0,
|
|
1312
|
+
const span = (0, mod_js_2.startClientSpan)(method, subject);
|
|
1222
1313
|
const attempt = async () => {
|
|
1223
1314
|
const authHeaders = await __classPrivateFieldGet(this, _Trellis_instances, "m", _Trellis_createProof).call(this, subject, msg);
|
|
1224
1315
|
const headers = (0, nats_core_1.headers)();
|
|
@@ -1226,7 +1317,7 @@ _Trellis_log = new WeakMap(), _Trellis_tasks = new WeakMap(), _Trellis_hasExplic
|
|
|
1226
1317
|
headers.set("proof", authHeaders.proof);
|
|
1227
1318
|
headers.set("iat", String(authHeaders.iat));
|
|
1228
1319
|
headers.set("request-id", authHeaders.requestId);
|
|
1229
|
-
(0,
|
|
1320
|
+
(0, mod_js_2.injectTraceContext)((0, mod_js_2.createNatsHeaderCarrier)(headers), span);
|
|
1230
1321
|
const msgResult = await __classPrivateFieldGet(this, _Trellis_instances, "m", _Trellis_requestMessageWithRetry).call(this, {
|
|
1231
1322
|
method,
|
|
1232
1323
|
subject,
|
|
@@ -1237,30 +1328,50 @@ _Trellis_log = new WeakMap(), _Trellis_tasks = new WeakMap(), _Trellis_hasExplic
|
|
|
1237
1328
|
});
|
|
1238
1329
|
const response = msgResult.take();
|
|
1239
1330
|
if ((0, result_1.isErr)(response)) {
|
|
1331
|
+
recordRuntimeError(response.error, {
|
|
1332
|
+
surface: "rpc",
|
|
1333
|
+
direction: "client",
|
|
1334
|
+
operation: method,
|
|
1335
|
+
phase: "request_send",
|
|
1336
|
+
});
|
|
1240
1337
|
return response;
|
|
1241
1338
|
}
|
|
1242
1339
|
if (response.headers?.get("status") === "error") {
|
|
1243
1340
|
const json = safeJson(response).take();
|
|
1244
1341
|
if ((0, result_1.isErr)(json)) {
|
|
1245
|
-
|
|
1342
|
+
const error = requestFailedTransportError({
|
|
1246
1343
|
code: "trellis.request.invalid_response",
|
|
1247
1344
|
message: "Trellis returned an invalid response.",
|
|
1248
1345
|
hint: "Retry the request. If it keeps happening, check the Trellis capability handling this request.",
|
|
1249
1346
|
method,
|
|
1250
1347
|
subject,
|
|
1251
1348
|
cause: json.error.cause,
|
|
1252
|
-
})
|
|
1349
|
+
});
|
|
1350
|
+
recordRuntimeError(error, {
|
|
1351
|
+
surface: "rpc",
|
|
1352
|
+
direction: "client",
|
|
1353
|
+
operation: method,
|
|
1354
|
+
phase: "response_decoding",
|
|
1355
|
+
});
|
|
1356
|
+
return (0, result_1.err)(error);
|
|
1253
1357
|
}
|
|
1254
1358
|
const errorData = (0, codec_js_1.parse)(TrellisError_js_1.TrellisErrorDataSchema, json).take();
|
|
1255
1359
|
if ((0, result_1.isErr)(errorData)) {
|
|
1256
|
-
|
|
1360
|
+
const error = requestFailedTransportError({
|
|
1257
1361
|
code: "trellis.request.invalid_response",
|
|
1258
1362
|
message: "Trellis returned an invalid response.",
|
|
1259
1363
|
hint: "Retry the request. If it keeps happening, check the Trellis capability handling this request.",
|
|
1260
1364
|
method,
|
|
1261
1365
|
subject,
|
|
1262
1366
|
cause: errorData.error,
|
|
1263
|
-
})
|
|
1367
|
+
});
|
|
1368
|
+
recordRuntimeError(error, {
|
|
1369
|
+
surface: "rpc",
|
|
1370
|
+
direction: "client",
|
|
1371
|
+
operation: method,
|
|
1372
|
+
phase: "response_decoding",
|
|
1373
|
+
});
|
|
1374
|
+
return (0, result_1.err)(error);
|
|
1264
1375
|
}
|
|
1265
1376
|
const declaredErrorTypes = Array.isArray(ctx.declaredErrorTypes)
|
|
1266
1377
|
? ctx.declaredErrorTypes.filter((value) => typeof value === "string")
|
|
@@ -1271,41 +1382,66 @@ _Trellis_log = new WeakMap(), _Trellis_tasks = new WeakMap(), _Trellis_hasExplic
|
|
|
1271
1382
|
const reconstructed = reconstructDeclaredRpcError(declaredErrorTypes, runtimeErrors, errorData, json);
|
|
1272
1383
|
if (reconstructed) {
|
|
1273
1384
|
await __classPrivateFieldGet(this, _Trellis_instances, "m", _Trellis_handleBrowserAuthRequired).call(this, reconstructed);
|
|
1385
|
+
recordRuntimeError(new RemoteError_js_1.RemoteError({ error: errorData }), {
|
|
1386
|
+
surface: "rpc",
|
|
1387
|
+
direction: "client",
|
|
1388
|
+
operation: method,
|
|
1389
|
+
phase: "remote_error",
|
|
1390
|
+
});
|
|
1274
1391
|
return (0, result_1.err)(reconstructed);
|
|
1275
1392
|
}
|
|
1276
1393
|
const remoteError = new RemoteError_js_1.RemoteError({ error: errorData });
|
|
1277
1394
|
await __classPrivateFieldGet(this, _Trellis_instances, "m", _Trellis_handleBrowserAuthRequired).call(this, remoteError);
|
|
1395
|
+
recordRuntimeError(remoteError, {
|
|
1396
|
+
surface: "rpc",
|
|
1397
|
+
direction: "client",
|
|
1398
|
+
operation: method,
|
|
1399
|
+
phase: "remote_error",
|
|
1400
|
+
});
|
|
1278
1401
|
return (0, result_1.err)(remoteError);
|
|
1279
1402
|
}
|
|
1280
1403
|
const json = safeJson(response).take();
|
|
1281
1404
|
if ((0, result_1.isErr)(json)) {
|
|
1282
|
-
|
|
1405
|
+
const error = requestFailedTransportError({
|
|
1283
1406
|
code: "trellis.request.invalid_response",
|
|
1284
1407
|
message: "Trellis returned an invalid response.",
|
|
1285
1408
|
hint: "Retry the request. If it keeps happening, check the Trellis capability handling this request.",
|
|
1286
1409
|
method,
|
|
1287
1410
|
subject,
|
|
1288
1411
|
cause: json.error.cause,
|
|
1289
|
-
})
|
|
1412
|
+
});
|
|
1413
|
+
recordRuntimeError(error, {
|
|
1414
|
+
surface: "rpc",
|
|
1415
|
+
direction: "client",
|
|
1416
|
+
operation: method,
|
|
1417
|
+
phase: "response_decoding",
|
|
1418
|
+
});
|
|
1419
|
+
return (0, result_1.err)(error);
|
|
1290
1420
|
}
|
|
1291
1421
|
const outputResult = parseRuntimeSchema(ctx.output, json).take();
|
|
1292
1422
|
if ((0, result_1.isErr)(outputResult)) {
|
|
1423
|
+
recordRuntimeError(outputResult.error, {
|
|
1424
|
+
surface: "rpc",
|
|
1425
|
+
direction: "client",
|
|
1426
|
+
operation: method,
|
|
1427
|
+
phase: "response_decoding",
|
|
1428
|
+
});
|
|
1293
1429
|
return (0, result_1.err)(outputResult.error);
|
|
1294
1430
|
}
|
|
1295
1431
|
return (0, result_1.ok)(outputResult);
|
|
1296
1432
|
};
|
|
1297
|
-
return await (0,
|
|
1433
|
+
return await (0, mod_js_2.withSpanAsync)(span, async () => {
|
|
1298
1434
|
try {
|
|
1299
1435
|
const result = await attempt();
|
|
1300
1436
|
const value = result.take();
|
|
1301
1437
|
if ((0, result_1.isErr)(value)) {
|
|
1302
1438
|
span.setStatus({
|
|
1303
|
-
code:
|
|
1439
|
+
code: mod_js_2.SpanStatusCode.ERROR,
|
|
1304
1440
|
message: value.error.message,
|
|
1305
1441
|
});
|
|
1306
1442
|
}
|
|
1307
1443
|
else {
|
|
1308
|
-
span.setStatus({ code:
|
|
1444
|
+
span.setStatus({ code: mod_js_2.SpanStatusCode.OK });
|
|
1309
1445
|
}
|
|
1310
1446
|
return result;
|
|
1311
1447
|
}
|
|
@@ -1314,10 +1450,16 @@ _Trellis_log = new WeakMap(), _Trellis_tasks = new WeakMap(), _Trellis_hasExplic
|
|
|
1314
1450
|
? cause
|
|
1315
1451
|
: new index_js_1.UnexpectedError({ cause });
|
|
1316
1452
|
span.setStatus({
|
|
1317
|
-
code:
|
|
1453
|
+
code: mod_js_2.SpanStatusCode.ERROR,
|
|
1318
1454
|
message: unexpected.message,
|
|
1319
1455
|
});
|
|
1320
1456
|
span.recordException(unexpected);
|
|
1457
|
+
recordRuntimeError(unexpected, {
|
|
1458
|
+
surface: "rpc",
|
|
1459
|
+
direction: "client",
|
|
1460
|
+
operation: method,
|
|
1461
|
+
phase: "unexpected",
|
|
1462
|
+
});
|
|
1321
1463
|
return (0, result_1.err)(unexpected);
|
|
1322
1464
|
}
|
|
1323
1465
|
finally {
|
|
@@ -1386,18 +1528,32 @@ _Trellis_log = new WeakMap(), _Trellis_tasks = new WeakMap(), _Trellis_hasExplic
|
|
|
1386
1528
|
}, _Trellis_subscribeFeed = function _Trellis_subscribeFeed(feed, descriptor, input, opts) {
|
|
1387
1529
|
return result_1.AsyncResult.from((async () => {
|
|
1388
1530
|
const payload = encodeRuntimeSchema(descriptor.input, input).take();
|
|
1389
|
-
if ((0, result_1.isErr)(payload))
|
|
1531
|
+
if ((0, result_1.isErr)(payload)) {
|
|
1532
|
+
recordRuntimeError(payload.error, {
|
|
1533
|
+
surface: "feed",
|
|
1534
|
+
direction: "client",
|
|
1535
|
+
operation: feed,
|
|
1536
|
+
phase: "request_encoding",
|
|
1537
|
+
});
|
|
1390
1538
|
return payload;
|
|
1539
|
+
}
|
|
1391
1540
|
const subject = this.template(descriptor.subject, input).take();
|
|
1392
|
-
if ((0, result_1.isErr)(subject))
|
|
1541
|
+
if ((0, result_1.isErr)(subject)) {
|
|
1542
|
+
recordRuntimeError(subject.error, {
|
|
1543
|
+
surface: "feed",
|
|
1544
|
+
direction: "client",
|
|
1545
|
+
operation: feed,
|
|
1546
|
+
phase: "request_template",
|
|
1547
|
+
});
|
|
1393
1548
|
return subject;
|
|
1549
|
+
}
|
|
1394
1550
|
const authHeaders = await __classPrivateFieldGet(this, _Trellis_instances, "m", _Trellis_createProof).call(this, subject, payload);
|
|
1395
1551
|
const headers = (0, nats_core_1.headers)();
|
|
1396
1552
|
headers.set("session-key", this.auth.sessionKey);
|
|
1397
1553
|
headers.set("proof", authHeaders.proof);
|
|
1398
1554
|
headers.set("iat", String(authHeaders.iat));
|
|
1399
1555
|
headers.set("request-id", authHeaders.requestId);
|
|
1400
|
-
(0,
|
|
1556
|
+
(0, mod_js_2.injectTraceContext)((0, mod_js_2.createNatsHeaderCarrier)(headers));
|
|
1401
1557
|
const inbox = (0, nats_core_1.createInbox)(`_INBOX.${this.auth.sessionKey.slice(0, 16)}`);
|
|
1402
1558
|
const sub = this.nats.subscribe(inbox);
|
|
1403
1559
|
const iterator = sub[Symbol.asyncIterator]();
|
|
@@ -1410,13 +1566,20 @@ _Trellis_log = new WeakMap(), _Trellis_tasks = new WeakMap(), _Trellis_hasExplic
|
|
|
1410
1566
|
catch (cause) {
|
|
1411
1567
|
opts?.signal?.removeEventListener("abort", abort);
|
|
1412
1568
|
sub.unsubscribe();
|
|
1413
|
-
|
|
1569
|
+
const error = createTransportError({
|
|
1414
1570
|
code: "trellis.feed.subscribe_failed",
|
|
1415
1571
|
message: "Trellis could not subscribe to the feed.",
|
|
1416
1572
|
hint: "Retry the subscription. If it keeps failing, check Trellis runtime health.",
|
|
1417
1573
|
cause,
|
|
1418
1574
|
context: { feed, subject },
|
|
1419
|
-
})
|
|
1575
|
+
});
|
|
1576
|
+
recordRuntimeError(error, {
|
|
1577
|
+
surface: "feed",
|
|
1578
|
+
direction: "client",
|
|
1579
|
+
operation: feed,
|
|
1580
|
+
phase: "request_send",
|
|
1581
|
+
});
|
|
1582
|
+
return (0, result_1.err)(error);
|
|
1420
1583
|
}
|
|
1421
1584
|
let timeoutId;
|
|
1422
1585
|
let abortHandler;
|
|
@@ -1442,7 +1605,7 @@ _Trellis_log = new WeakMap(), _Trellis_tasks = new WeakMap(), _Trellis_hasExplic
|
|
|
1442
1605
|
if (firstFrame === "timeout" || firstFrame === "aborted") {
|
|
1443
1606
|
opts?.signal?.removeEventListener("abort", abort);
|
|
1444
1607
|
sub.unsubscribe();
|
|
1445
|
-
|
|
1608
|
+
const error = createTransportError({
|
|
1446
1609
|
code: firstFrame === "timeout"
|
|
1447
1610
|
? "trellis.feed.subscribe_timeout"
|
|
1448
1611
|
: "trellis.feed.subscribe_aborted",
|
|
@@ -1453,28 +1616,49 @@ _Trellis_log = new WeakMap(), _Trellis_tasks = new WeakMap(), _Trellis_hasExplic
|
|
|
1453
1616
|
? "Check that the target service is running and has the current deployment digest, then retry."
|
|
1454
1617
|
: "Retry the subscription if the feed is still needed.",
|
|
1455
1618
|
context: { feed, subject },
|
|
1456
|
-
})
|
|
1619
|
+
});
|
|
1620
|
+
recordRuntimeError(error, {
|
|
1621
|
+
surface: "feed",
|
|
1622
|
+
direction: "client",
|
|
1623
|
+
operation: feed,
|
|
1624
|
+
phase: "handshake",
|
|
1625
|
+
});
|
|
1626
|
+
return (0, result_1.err)(error);
|
|
1457
1627
|
}
|
|
1458
1628
|
if (firstFrame.done) {
|
|
1459
1629
|
opts?.signal?.removeEventListener("abort", abort);
|
|
1460
1630
|
sub.unsubscribe();
|
|
1461
|
-
|
|
1631
|
+
const error = createTransportError({
|
|
1462
1632
|
code: "trellis.feed.subscribe_closed",
|
|
1463
1633
|
message: "Trellis closed the feed before acknowledging it.",
|
|
1464
1634
|
hint: "Retry the subscription. If it keeps failing, check Trellis runtime health.",
|
|
1465
1635
|
context: { feed, subject },
|
|
1466
|
-
})
|
|
1636
|
+
});
|
|
1637
|
+
recordRuntimeError(error, {
|
|
1638
|
+
surface: "feed",
|
|
1639
|
+
direction: "client",
|
|
1640
|
+
operation: feed,
|
|
1641
|
+
phase: "handshake",
|
|
1642
|
+
});
|
|
1643
|
+
return (0, result_1.err)(error);
|
|
1467
1644
|
}
|
|
1468
1645
|
const firstMessage = firstFrame.value;
|
|
1469
1646
|
if (firstMessage.headers?.get("status") === "error") {
|
|
1470
1647
|
opts?.signal?.removeEventListener("abort", abort);
|
|
1471
1648
|
sub.unsubscribe();
|
|
1472
|
-
|
|
1649
|
+
const error = createTransportError({
|
|
1473
1650
|
code: "trellis.feed.failed",
|
|
1474
1651
|
message: "Trellis rejected the feed subscription.",
|
|
1475
1652
|
hint: "Retry the subscription. If it keeps failing, check Trellis runtime health and permissions.",
|
|
1476
1653
|
context: { feed, subject, frame: firstMessage.string() },
|
|
1477
|
-
})
|
|
1654
|
+
});
|
|
1655
|
+
recordRuntimeError(error, {
|
|
1656
|
+
surface: "feed",
|
|
1657
|
+
direction: "client",
|
|
1658
|
+
operation: feed,
|
|
1659
|
+
phase: "remote_error",
|
|
1660
|
+
});
|
|
1661
|
+
return (0, result_1.err)(error);
|
|
1478
1662
|
}
|
|
1479
1663
|
const firstEvent = firstMessage.headers?.get("feed-status") === "ready"
|
|
1480
1664
|
? undefined
|
|
@@ -1484,19 +1668,40 @@ _Trellis_log = new WeakMap(), _Trellis_tasks = new WeakMap(), _Trellis_hasExplic
|
|
|
1484
1668
|
try {
|
|
1485
1669
|
const parseFeedFrame = (msg) => {
|
|
1486
1670
|
if (msg.headers?.get("status") === "error") {
|
|
1487
|
-
|
|
1671
|
+
const error = createTransportError({
|
|
1488
1672
|
code: "trellis.feed.failed",
|
|
1489
1673
|
message: "Trellis stopped the feed.",
|
|
1490
1674
|
hint: "Retry the subscription. If it keeps failing, check Trellis runtime health.",
|
|
1491
1675
|
context: { feed, subject, frame: msg.string() },
|
|
1492
1676
|
});
|
|
1677
|
+
recordRuntimeError(error, {
|
|
1678
|
+
surface: "feed",
|
|
1679
|
+
direction: "client",
|
|
1680
|
+
operation: feed,
|
|
1681
|
+
phase: "remote_error",
|
|
1682
|
+
});
|
|
1683
|
+
throw error;
|
|
1493
1684
|
}
|
|
1494
1685
|
const json = safeJson(msg).take();
|
|
1495
|
-
if ((0, result_1.isErr)(json))
|
|
1686
|
+
if ((0, result_1.isErr)(json)) {
|
|
1687
|
+
recordRuntimeError(json.error, {
|
|
1688
|
+
surface: "feed",
|
|
1689
|
+
direction: "client",
|
|
1690
|
+
operation: feed,
|
|
1691
|
+
phase: "event_decoding",
|
|
1692
|
+
});
|
|
1496
1693
|
throw json.error;
|
|
1694
|
+
}
|
|
1497
1695
|
const parsed = parseRuntimeSchema(eventSchema, json).take();
|
|
1498
|
-
if ((0, result_1.isErr)(parsed))
|
|
1696
|
+
if ((0, result_1.isErr)(parsed)) {
|
|
1697
|
+
recordRuntimeError(parsed.error, {
|
|
1698
|
+
surface: "feed",
|
|
1699
|
+
direction: "client",
|
|
1700
|
+
operation: feed,
|
|
1701
|
+
phase: "event_validation",
|
|
1702
|
+
});
|
|
1499
1703
|
throw parsed.error;
|
|
1704
|
+
}
|
|
1500
1705
|
return parsed;
|
|
1501
1706
|
};
|
|
1502
1707
|
if (firstEvent)
|
|
@@ -1524,13 +1729,20 @@ _Trellis_log = new WeakMap(), _Trellis_tasks = new WeakMap(), _Trellis_hasExplic
|
|
|
1524
1729
|
await this.nats.flush();
|
|
1525
1730
|
}
|
|
1526
1731
|
catch (cause) {
|
|
1527
|
-
|
|
1732
|
+
const error = createTransportError({
|
|
1528
1733
|
code: "trellis.feed.listen_failed",
|
|
1529
1734
|
message: "Trellis could not listen for feed requests.",
|
|
1530
1735
|
hint: "Check the service deployment digest and runtime permissions, then restart the service.",
|
|
1531
1736
|
cause,
|
|
1532
1737
|
context: { feed, subject },
|
|
1533
1738
|
});
|
|
1739
|
+
recordRuntimeError(error, {
|
|
1740
|
+
surface: "feed",
|
|
1741
|
+
direction: "server",
|
|
1742
|
+
operation: feed,
|
|
1743
|
+
phase: "listen",
|
|
1744
|
+
});
|
|
1745
|
+
throw error;
|
|
1534
1746
|
}
|
|
1535
1747
|
const task = result_1.AsyncResult.try(async () => {
|
|
1536
1748
|
for await (const msg of sub) {
|
|
@@ -1543,9 +1755,20 @@ _Trellis_log = new WeakMap(), _Trellis_tasks = new WeakMap(), _Trellis_hasExplic
|
|
|
1543
1755
|
}
|
|
1544
1756
|
}
|
|
1545
1757
|
catch (cause) {
|
|
1546
|
-
const error = cause
|
|
1547
|
-
|
|
1548
|
-
:
|
|
1758
|
+
const error = annotateHandlerBoundaryError(cause, {
|
|
1759
|
+
feed,
|
|
1760
|
+
requestId: msg.headers?.get("request-id"),
|
|
1761
|
+
service: this.name,
|
|
1762
|
+
contractId: this.contractId,
|
|
1763
|
+
contractDigest: this.contractDigest,
|
|
1764
|
+
traceId: traceIdFromTraceparent(msg.headers?.get("traceparent")),
|
|
1765
|
+
});
|
|
1766
|
+
recordRuntimeError(error, {
|
|
1767
|
+
surface: "feed",
|
|
1768
|
+
direction: "server",
|
|
1769
|
+
operation: feed,
|
|
1770
|
+
phase: "handler_throw",
|
|
1771
|
+
});
|
|
1549
1772
|
__classPrivateFieldGet(this, _Trellis_instances, "m", _Trellis_respondWithError).call(this, msg, error);
|
|
1550
1773
|
}
|
|
1551
1774
|
})();
|
|
@@ -1554,11 +1777,25 @@ _Trellis_log = new WeakMap(), _Trellis_tasks = new WeakMap(), _Trellis_hasExplic
|
|
|
1554
1777
|
__classPrivateFieldGet(this, _Trellis_tasks, "f").add(`feed:${feed}`, task);
|
|
1555
1778
|
}, _Trellis_processFeedMessage = async function _Trellis_processFeedMessage(feed, descriptor, msg, handler) {
|
|
1556
1779
|
const json = safeJson(msg).take();
|
|
1557
|
-
if ((0, result_1.isErr)(json))
|
|
1780
|
+
if ((0, result_1.isErr)(json)) {
|
|
1781
|
+
recordRuntimeError(json.error, {
|
|
1782
|
+
surface: "feed",
|
|
1783
|
+
direction: "server",
|
|
1784
|
+
operation: feed,
|
|
1785
|
+
phase: "request_decoding",
|
|
1786
|
+
});
|
|
1558
1787
|
return json;
|
|
1788
|
+
}
|
|
1559
1789
|
const parsed = parseRuntimeSchema(descriptor.input, json).take();
|
|
1560
|
-
if ((0, result_1.isErr)(parsed))
|
|
1790
|
+
if ((0, result_1.isErr)(parsed)) {
|
|
1791
|
+
recordRuntimeError(parsed.error, {
|
|
1792
|
+
surface: "feed",
|
|
1793
|
+
direction: "server",
|
|
1794
|
+
operation: feed,
|
|
1795
|
+
phase: "input_validation",
|
|
1796
|
+
});
|
|
1561
1797
|
return parsed;
|
|
1798
|
+
}
|
|
1562
1799
|
const caller = await __classPrivateFieldGet(this, _Trellis_instances, "m", _Trellis_authenticateFeedRequest).call(this, {
|
|
1563
1800
|
feed,
|
|
1564
1801
|
subject: msg.subject,
|
|
@@ -1567,12 +1804,26 @@ _Trellis_log = new WeakMap(), _Trellis_tasks = new WeakMap(), _Trellis_hasExplic
|
|
|
1567
1804
|
requiredCapabilities: descriptor.subscribeCapabilities,
|
|
1568
1805
|
});
|
|
1569
1806
|
const callerValue = caller.take();
|
|
1570
|
-
if ((0, result_1.isErr)(callerValue))
|
|
1807
|
+
if ((0, result_1.isErr)(callerValue)) {
|
|
1808
|
+
recordRuntimeError(callerValue.error, {
|
|
1809
|
+
surface: "feed",
|
|
1810
|
+
direction: "server",
|
|
1811
|
+
operation: feed,
|
|
1812
|
+
phase: "auth",
|
|
1813
|
+
});
|
|
1571
1814
|
return callerValue;
|
|
1815
|
+
}
|
|
1572
1816
|
if (!msg.reply) {
|
|
1573
|
-
|
|
1817
|
+
const error = new index_js_1.UnexpectedError({
|
|
1574
1818
|
context: { feed, reason: "missing_reply" },
|
|
1575
|
-
})
|
|
1819
|
+
});
|
|
1820
|
+
recordRuntimeError(error, {
|
|
1821
|
+
surface: "feed",
|
|
1822
|
+
direction: "server",
|
|
1823
|
+
operation: feed,
|
|
1824
|
+
phase: "handshake",
|
|
1825
|
+
});
|
|
1826
|
+
return (0, result_1.err)(error);
|
|
1576
1827
|
}
|
|
1577
1828
|
const readyHeaders = (0, nats_core_1.headers)();
|
|
1578
1829
|
readyHeaders.set("feed-status", "ready");
|
|
@@ -1580,24 +1831,73 @@ _Trellis_log = new WeakMap(), _Trellis_tasks = new WeakMap(), _Trellis_hasExplic
|
|
|
1580
1831
|
await this.nats.flush();
|
|
1581
1832
|
const controller = new AbortController();
|
|
1582
1833
|
try {
|
|
1583
|
-
await handler({
|
|
1834
|
+
const handlerResult = await handler({
|
|
1584
1835
|
input: parsed,
|
|
1585
1836
|
caller: callerValue,
|
|
1586
1837
|
signal: controller.signal,
|
|
1587
1838
|
emit: (event) => result_1.AsyncResult.from((async () => {
|
|
1588
1839
|
const payload = encodeRuntimeSchema(descriptor.event, event).take();
|
|
1589
|
-
if ((0, result_1.isErr)(payload))
|
|
1840
|
+
if ((0, result_1.isErr)(payload)) {
|
|
1841
|
+
recordRuntimeError(payload.error, {
|
|
1842
|
+
surface: "feed",
|
|
1843
|
+
direction: "server",
|
|
1844
|
+
operation: feed,
|
|
1845
|
+
phase: "event_encoding",
|
|
1846
|
+
});
|
|
1590
1847
|
return payload;
|
|
1848
|
+
}
|
|
1591
1849
|
if (!msg.reply) {
|
|
1592
|
-
|
|
1850
|
+
const error = new index_js_1.UnexpectedError({
|
|
1593
1851
|
context: { feed, reason: "missing_reply" },
|
|
1594
|
-
})
|
|
1852
|
+
});
|
|
1853
|
+
recordRuntimeError(error, {
|
|
1854
|
+
surface: "feed",
|
|
1855
|
+
direction: "server",
|
|
1856
|
+
operation: feed,
|
|
1857
|
+
phase: "event_publish",
|
|
1858
|
+
});
|
|
1859
|
+
return (0, result_1.err)(error);
|
|
1860
|
+
}
|
|
1861
|
+
try {
|
|
1862
|
+
this.nats.publish(msg.reply, payload);
|
|
1863
|
+
await this.nats.flush();
|
|
1864
|
+
}
|
|
1865
|
+
catch (cause) {
|
|
1866
|
+
const error = new index_js_1.UnexpectedError({
|
|
1867
|
+
cause,
|
|
1868
|
+
context: { feed },
|
|
1869
|
+
});
|
|
1870
|
+
recordRuntimeError(error, {
|
|
1871
|
+
surface: "feed",
|
|
1872
|
+
direction: "server",
|
|
1873
|
+
operation: feed,
|
|
1874
|
+
phase: "event_publish",
|
|
1875
|
+
});
|
|
1876
|
+
return (0, result_1.err)(error);
|
|
1595
1877
|
}
|
|
1596
|
-
this.nats.publish(msg.reply, payload);
|
|
1597
|
-
await this.nats.flush();
|
|
1598
1878
|
return (0, result_1.ok)(undefined);
|
|
1599
1879
|
})()),
|
|
1600
1880
|
});
|
|
1881
|
+
const handlerOutcome = isResultLike(handlerResult)
|
|
1882
|
+
? handlerResult.take()
|
|
1883
|
+
: handlerResult;
|
|
1884
|
+
if ((0, result_1.isErr)(handlerOutcome)) {
|
|
1885
|
+
const error = annotateHandlerBoundaryError(handlerOutcome.error, {
|
|
1886
|
+
feed,
|
|
1887
|
+
requestId: msg.headers?.get("request-id"),
|
|
1888
|
+
service: this.name,
|
|
1889
|
+
contractId: this.contractId,
|
|
1890
|
+
contractDigest: this.contractDigest,
|
|
1891
|
+
traceId: traceIdFromTraceparent(msg.headers?.get("traceparent")),
|
|
1892
|
+
});
|
|
1893
|
+
recordRuntimeError(error, {
|
|
1894
|
+
surface: "feed",
|
|
1895
|
+
direction: "server",
|
|
1896
|
+
operation: feed,
|
|
1897
|
+
phase: "handler_result",
|
|
1898
|
+
});
|
|
1899
|
+
return (0, result_1.err)(error);
|
|
1900
|
+
}
|
|
1601
1901
|
return (0, result_1.ok)(undefined);
|
|
1602
1902
|
}
|
|
1603
1903
|
finally {
|
|
@@ -1648,31 +1948,43 @@ _Trellis_log = new WeakMap(), _Trellis_tasks = new WeakMap(), _Trellis_hasExplic
|
|
|
1648
1948
|
}, _Trellis_processRPCMessage = async function _Trellis_processRPCMessage(method, ctx, msg, fn, handlerTrellis) {
|
|
1649
1949
|
__classPrivateFieldGet(this, _Trellis_log, "f").debug({ method: String(method), subject: msg.subject }, "Processing RPC message");
|
|
1650
1950
|
// Extract trace context from incoming NATS headers
|
|
1651
|
-
const parentContext = (0,
|
|
1951
|
+
const parentContext = (0, mod_js_2.extractTraceContext)((0, mod_js_2.createNatsHeaderCarrier)({
|
|
1652
1952
|
get: (k) => msg.headers?.get(k) ?? undefined,
|
|
1653
1953
|
set: () => { }, // Server doesn't need to set headers on incoming messages
|
|
1654
1954
|
}));
|
|
1655
1955
|
// Start a server span for this RPC handler
|
|
1656
|
-
const span = (0,
|
|
1956
|
+
const span = (0, mod_js_2.startServerSpan)(method, msg.subject, parentContext);
|
|
1657
1957
|
const incomingTraceId = traceIdFromTraceparent(msg.headers?.get("traceparent"));
|
|
1658
1958
|
// Execute the handler within the span's context
|
|
1659
|
-
return (0,
|
|
1959
|
+
return (0, mod_js_2.withSpanAsync)(span, async () => {
|
|
1660
1960
|
const execute = async () => {
|
|
1661
1961
|
const jsonData = safeJson(msg).take();
|
|
1662
1962
|
if ((0, result_1.isErr)(jsonData)) {
|
|
1663
1963
|
__classPrivateFieldGet(this, _Trellis_log, "f").warn({ method, error: jsonData.error.message }, "Failed to parse JSON");
|
|
1664
1964
|
span.setStatus({
|
|
1665
|
-
code:
|
|
1965
|
+
code: mod_js_2.SpanStatusCode.ERROR,
|
|
1666
1966
|
message: "Failed to parse JSON",
|
|
1667
1967
|
});
|
|
1968
|
+
recordRuntimeError(jsonData.error, {
|
|
1969
|
+
surface: "rpc",
|
|
1970
|
+
direction: "server",
|
|
1971
|
+
operation: String(method),
|
|
1972
|
+
phase: "parse",
|
|
1973
|
+
});
|
|
1668
1974
|
return jsonData;
|
|
1669
1975
|
}
|
|
1670
1976
|
const parsedInput = parseRuntimeSchema(ctx.input, jsonData).take();
|
|
1671
1977
|
if ((0, result_1.isErr)(parsedInput)) {
|
|
1672
1978
|
span.setStatus({
|
|
1673
|
-
code:
|
|
1979
|
+
code: mod_js_2.SpanStatusCode.ERROR,
|
|
1674
1980
|
message: "Input validation failed",
|
|
1675
1981
|
});
|
|
1982
|
+
recordRuntimeError(parsedInput.error, {
|
|
1983
|
+
surface: "rpc",
|
|
1984
|
+
direction: "server",
|
|
1985
|
+
operation: String(method),
|
|
1986
|
+
phase: "input_validation",
|
|
1987
|
+
});
|
|
1676
1988
|
return parsedInput;
|
|
1677
1989
|
}
|
|
1678
1990
|
let caller;
|
|
@@ -1695,22 +2007,43 @@ _Trellis_log = new WeakMap(), _Trellis_tasks = new WeakMap(), _Trellis_hasExplic
|
|
|
1695
2007
|
if (!sessionKey) {
|
|
1696
2008
|
__classPrivateFieldGet(this, _Trellis_log, "f").warn({ method }, "Missing session-key header");
|
|
1697
2009
|
span.setStatus({
|
|
1698
|
-
code:
|
|
2010
|
+
code: mod_js_2.SpanStatusCode.ERROR,
|
|
1699
2011
|
message: "Missing session-key",
|
|
1700
2012
|
});
|
|
1701
|
-
|
|
2013
|
+
const error = new index_js_1.AuthError({ reason: "missing_session_key" });
|
|
2014
|
+
recordRuntimeError(error, {
|
|
2015
|
+
surface: "rpc",
|
|
2016
|
+
direction: "server",
|
|
2017
|
+
operation: String(method),
|
|
2018
|
+
phase: "auth",
|
|
2019
|
+
});
|
|
2020
|
+
return (0, result_1.err)(error);
|
|
1702
2021
|
}
|
|
1703
2022
|
if (!proof) {
|
|
1704
2023
|
__classPrivateFieldGet(this, _Trellis_log, "f").warn({ method }, "Missing proof in request");
|
|
1705
2024
|
span.setStatus({
|
|
1706
|
-
code:
|
|
2025
|
+
code: mod_js_2.SpanStatusCode.ERROR,
|
|
1707
2026
|
message: "Missing proof",
|
|
1708
2027
|
});
|
|
1709
|
-
|
|
2028
|
+
const error = new index_js_1.AuthError({ reason: "missing_proof" });
|
|
2029
|
+
recordRuntimeError(error, {
|
|
2030
|
+
surface: "rpc",
|
|
2031
|
+
direction: "server",
|
|
2032
|
+
operation: String(method),
|
|
2033
|
+
phase: "auth",
|
|
2034
|
+
});
|
|
2035
|
+
return (0, result_1.err)(error);
|
|
1710
2036
|
}
|
|
1711
2037
|
const iat = Number(iatHeader);
|
|
1712
2038
|
if (!Number.isSafeInteger(iat) || !requestId) {
|
|
1713
|
-
|
|
2039
|
+
const error = new index_js_1.AuthError({ reason: "invalid_signature" });
|
|
2040
|
+
recordRuntimeError(error, {
|
|
2041
|
+
surface: "rpc",
|
|
2042
|
+
direction: "server",
|
|
2043
|
+
operation: String(method),
|
|
2044
|
+
phase: "auth",
|
|
2045
|
+
});
|
|
2046
|
+
return (0, result_1.err)(error);
|
|
1714
2047
|
}
|
|
1715
2048
|
// Verify proof signature locally using the raw request bytes we received.
|
|
1716
2049
|
const payloadBytes = msg.data ?? new Uint8Array();
|
|
@@ -1726,13 +2059,20 @@ _Trellis_log = new WeakMap(), _Trellis_tasks = new WeakMap(), _Trellis_hasExplic
|
|
|
1726
2059
|
verifyResult.take() === true;
|
|
1727
2060
|
if (!signatureOk) {
|
|
1728
2061
|
span.setStatus({
|
|
1729
|
-
code:
|
|
2062
|
+
code: mod_js_2.SpanStatusCode.ERROR,
|
|
1730
2063
|
message: "Invalid signature",
|
|
1731
2064
|
});
|
|
1732
|
-
|
|
2065
|
+
const error = new index_js_1.AuthError({
|
|
1733
2066
|
reason: "invalid_signature",
|
|
1734
2067
|
context: { sessionKey },
|
|
1735
|
-
})
|
|
2068
|
+
});
|
|
2069
|
+
recordRuntimeError(error, {
|
|
2070
|
+
surface: "rpc",
|
|
2071
|
+
direction: "server",
|
|
2072
|
+
operation: String(method),
|
|
2073
|
+
phase: "auth",
|
|
2074
|
+
});
|
|
2075
|
+
return (0, result_1.err)(error);
|
|
1736
2076
|
}
|
|
1737
2077
|
let auth;
|
|
1738
2078
|
for (let attempt = 0; attempt < DEFAULT_AUTH_VALIDATE_SESSION_RETRY_ATTEMPTS; attempt++) {
|
|
@@ -1758,9 +2098,16 @@ _Trellis_log = new WeakMap(), _Trellis_tasks = new WeakMap(), _Trellis_hasExplic
|
|
|
1758
2098
|
await sleep(DEFAULT_AUTH_VALIDATE_SESSION_RETRY_MS * (attempt + 1));
|
|
1759
2099
|
}
|
|
1760
2100
|
if (!auth) {
|
|
1761
|
-
|
|
2101
|
+
const error = new index_js_1.UnexpectedError({
|
|
1762
2102
|
context: { reason: "missing_auth_validate_result" },
|
|
1763
|
-
})
|
|
2103
|
+
});
|
|
2104
|
+
recordRuntimeError(error, {
|
|
2105
|
+
surface: "rpc",
|
|
2106
|
+
direction: "server",
|
|
2107
|
+
operation: String(method),
|
|
2108
|
+
phase: "auth",
|
|
2109
|
+
});
|
|
2110
|
+
return (0, result_1.err)(error);
|
|
1764
2111
|
}
|
|
1765
2112
|
if (auth instanceof Error) {
|
|
1766
2113
|
__classPrivateFieldGet(this, _Trellis_log, "f").warn({
|
|
@@ -1772,37 +2119,64 @@ _Trellis_log = new WeakMap(), _Trellis_tasks = new WeakMap(), _Trellis_hasExplic
|
|
|
1772
2119
|
: undefined,
|
|
1773
2120
|
}, "Auth.Requests.Validate failed");
|
|
1774
2121
|
span.setStatus({
|
|
1775
|
-
code:
|
|
2122
|
+
code: mod_js_2.SpanStatusCode.ERROR,
|
|
1776
2123
|
message: "Auth.Requests.Validate failed",
|
|
1777
2124
|
});
|
|
1778
2125
|
if (auth instanceof result_1.BaseError) {
|
|
2126
|
+
recordRuntimeError(auth, {
|
|
2127
|
+
surface: "rpc",
|
|
2128
|
+
direction: "server",
|
|
2129
|
+
operation: String(method),
|
|
2130
|
+
phase: "auth",
|
|
2131
|
+
});
|
|
1779
2132
|
return (0, result_1.err)(auth);
|
|
1780
2133
|
}
|
|
1781
|
-
|
|
2134
|
+
const error = new index_js_1.UnexpectedError({ cause: auth });
|
|
2135
|
+
recordRuntimeError(error, {
|
|
2136
|
+
surface: "rpc",
|
|
2137
|
+
direction: "server",
|
|
2138
|
+
operation: String(method),
|
|
2139
|
+
phase: "auth",
|
|
2140
|
+
});
|
|
2141
|
+
return (0, result_1.err)(error);
|
|
1782
2142
|
}
|
|
1783
2143
|
if (!auth.allowed) {
|
|
1784
2144
|
span.setStatus({
|
|
1785
|
-
code:
|
|
2145
|
+
code: mod_js_2.SpanStatusCode.ERROR,
|
|
1786
2146
|
message: "Insufficient permissions",
|
|
1787
2147
|
});
|
|
1788
|
-
|
|
2148
|
+
const error = new index_js_1.AuthError({
|
|
1789
2149
|
reason: "insufficient_permissions",
|
|
1790
2150
|
context: {
|
|
1791
2151
|
requiredCapabilities: ctx.callerCapabilities,
|
|
1792
2152
|
userCapabilities: auth.caller.capabilities,
|
|
1793
2153
|
},
|
|
1794
|
-
})
|
|
2154
|
+
});
|
|
2155
|
+
recordRuntimeError(error, {
|
|
2156
|
+
surface: "rpc",
|
|
2157
|
+
direction: "server",
|
|
2158
|
+
operation: String(method),
|
|
2159
|
+
phase: "auth",
|
|
2160
|
+
});
|
|
2161
|
+
return (0, result_1.err)(error);
|
|
1795
2162
|
}
|
|
1796
2163
|
if (typeof msg.reply !== "string" ||
|
|
1797
2164
|
!msg.reply.startsWith(`${auth.inboxPrefix}.`)) {
|
|
1798
2165
|
span.setStatus({
|
|
1799
|
-
code:
|
|
2166
|
+
code: mod_js_2.SpanStatusCode.ERROR,
|
|
1800
2167
|
message: "Reply subject mismatch",
|
|
1801
2168
|
});
|
|
1802
|
-
|
|
2169
|
+
const error = new index_js_1.AuthError({
|
|
1803
2170
|
reason: "reply_subject_mismatch",
|
|
1804
2171
|
context: { expected: auth.inboxPrefix, actual: msg.reply },
|
|
1805
|
-
})
|
|
2172
|
+
});
|
|
2173
|
+
recordRuntimeError(error, {
|
|
2174
|
+
surface: "rpc",
|
|
2175
|
+
direction: "server",
|
|
2176
|
+
operation: String(method),
|
|
2177
|
+
phase: "auth",
|
|
2178
|
+
});
|
|
2179
|
+
return (0, result_1.err)(error);
|
|
1806
2180
|
}
|
|
1807
2181
|
caller = auth.caller;
|
|
1808
2182
|
}
|
|
@@ -1830,7 +2204,14 @@ _Trellis_log = new WeakMap(), _Trellis_tasks = new WeakMap(), _Trellis_hasExplic
|
|
|
1830
2204
|
client: handlerTrellis,
|
|
1831
2205
|
})));
|
|
1832
2206
|
if (handlerResultWrapped.isErr()) {
|
|
1833
|
-
const error = handlerResultWrapped.error
|
|
2207
|
+
const error = annotateHandlerBoundaryError(handlerResultWrapped.error, {
|
|
2208
|
+
method: String(method),
|
|
2209
|
+
requestId: msg.headers?.get("request-id"),
|
|
2210
|
+
service: this.name,
|
|
2211
|
+
contractId: this.contractId,
|
|
2212
|
+
contractDigest: this.contractDigest,
|
|
2213
|
+
traceId: activeTraceId(span) ?? incomingTraceId,
|
|
2214
|
+
});
|
|
1834
2215
|
__classPrivateFieldGet(this, _Trellis_log, "f").error({
|
|
1835
2216
|
method,
|
|
1836
2217
|
error: error.message,
|
|
@@ -1839,20 +2220,29 @@ _Trellis_log = new WeakMap(), _Trellis_tasks = new WeakMap(), _Trellis_hasExplic
|
|
|
1839
2220
|
: error.cause,
|
|
1840
2221
|
}, "Handler threw unexpectedly.");
|
|
1841
2222
|
span.setStatus({
|
|
1842
|
-
code:
|
|
2223
|
+
code: mod_js_2.SpanStatusCode.ERROR,
|
|
1843
2224
|
message: error.message,
|
|
1844
2225
|
});
|
|
1845
2226
|
span.recordException(error);
|
|
2227
|
+
recordRuntimeError(error, {
|
|
2228
|
+
surface: "rpc",
|
|
2229
|
+
direction: "server",
|
|
2230
|
+
operation: String(method),
|
|
2231
|
+
phase: "handler_throw",
|
|
2232
|
+
});
|
|
1846
2233
|
return (0, result_1.err)(error);
|
|
1847
2234
|
}
|
|
1848
2235
|
const handlerResult = handlerResultWrapped.take();
|
|
1849
2236
|
const handlerOutcome = handlerResult.take();
|
|
1850
2237
|
if ((0, result_1.isErr)(handlerOutcome)) {
|
|
1851
|
-
const
|
|
1852
|
-
|
|
1853
|
-
|
|
1854
|
-
|
|
1855
|
-
:
|
|
2238
|
+
const error = annotateHandlerBoundaryError(handlerOutcome.error, {
|
|
2239
|
+
method: String(method),
|
|
2240
|
+
requestId: msg.headers?.get("request-id"),
|
|
2241
|
+
service: this.name,
|
|
2242
|
+
contractId: this.contractId,
|
|
2243
|
+
contractDigest: this.contractDigest,
|
|
2244
|
+
traceId: activeTraceId(span) ?? incomingTraceId,
|
|
2245
|
+
});
|
|
1856
2246
|
__classPrivateFieldGet(this, _Trellis_log, "f").error({
|
|
1857
2247
|
method,
|
|
1858
2248
|
error: error.message,
|
|
@@ -1862,20 +2252,32 @@ _Trellis_log = new WeakMap(), _Trellis_tasks = new WeakMap(), _Trellis_hasExplic
|
|
|
1862
2252
|
: error.cause,
|
|
1863
2253
|
}, "Handler returned error.");
|
|
1864
2254
|
span.setStatus({
|
|
1865
|
-
code:
|
|
2255
|
+
code: mod_js_2.SpanStatusCode.ERROR,
|
|
1866
2256
|
message: error.message,
|
|
1867
2257
|
});
|
|
2258
|
+
recordRuntimeError(error, {
|
|
2259
|
+
surface: "rpc",
|
|
2260
|
+
direction: "server",
|
|
2261
|
+
operation: String(method),
|
|
2262
|
+
phase: "handler_result",
|
|
2263
|
+
});
|
|
1868
2264
|
return (0, result_1.err)(error);
|
|
1869
2265
|
}
|
|
1870
2266
|
const encoded = (0, codec_js_1.encodeSchema)(ctx.output, handlerOutcome).take();
|
|
1871
2267
|
if ((0, result_1.isErr)(encoded)) {
|
|
1872
2268
|
span.setStatus({
|
|
1873
|
-
code:
|
|
2269
|
+
code: mod_js_2.SpanStatusCode.ERROR,
|
|
1874
2270
|
message: "Output encoding failed",
|
|
1875
2271
|
});
|
|
2272
|
+
recordRuntimeError(encoded.error, {
|
|
2273
|
+
surface: "rpc",
|
|
2274
|
+
direction: "server",
|
|
2275
|
+
operation: String(method),
|
|
2276
|
+
phase: "output_encoding",
|
|
2277
|
+
});
|
|
1876
2278
|
return encoded;
|
|
1877
2279
|
}
|
|
1878
|
-
span.setStatus({ code:
|
|
2280
|
+
span.setStatus({ code: mod_js_2.SpanStatusCode.OK });
|
|
1879
2281
|
return (0, result_1.ok)(encoded);
|
|
1880
2282
|
};
|
|
1881
2283
|
const result = await execute();
|
|
@@ -1949,17 +2351,31 @@ _Trellis_log = new WeakMap(), _Trellis_tasks = new WeakMap(), _Trellis_hasExplic
|
|
|
1949
2351
|
const m = parsedEvent.take();
|
|
1950
2352
|
if ((0, result_1.isErr)(m)) {
|
|
1951
2353
|
__classPrivateFieldGet(this, _Trellis_log, "f").error({ error: m.error }, "Event validation failed");
|
|
2354
|
+
recordRuntimeError(m.error, {
|
|
2355
|
+
surface: "event",
|
|
2356
|
+
direction: "consumer",
|
|
2357
|
+
operation: String(event),
|
|
2358
|
+
phase: "input_validation",
|
|
2359
|
+
});
|
|
1952
2360
|
continue;
|
|
1953
2361
|
}
|
|
1954
|
-
const handlerResult = await
|
|
2362
|
+
const handlerResult = await __classPrivateFieldGet(this, _Trellis_instances, "m", _Trellis_invokeEventHandler).call(this, {
|
|
2363
|
+
event,
|
|
1955
2364
|
payload: m,
|
|
1956
|
-
subject: msg.subject,
|
|
1957
2365
|
mode: "ephemeral",
|
|
1958
2366
|
message: msg,
|
|
1959
|
-
|
|
1960
|
-
|
|
2367
|
+
fn,
|
|
2368
|
+
});
|
|
2369
|
+
const handlerValue = handlerResult.take();
|
|
2370
|
+
if ((0, result_1.isErr)(handlerValue)) {
|
|
2371
|
+
recordRuntimeError(handlerValue.error, {
|
|
2372
|
+
surface: "event",
|
|
2373
|
+
direction: "consumer",
|
|
2374
|
+
operation: String(event),
|
|
2375
|
+
phase: "handler_result",
|
|
2376
|
+
});
|
|
1961
2377
|
__classPrivateFieldGet(this, _Trellis_log, "f").error({
|
|
1962
|
-
error:
|
|
2378
|
+
error: handlerValue.error.toSerializable(),
|
|
1963
2379
|
event,
|
|
1964
2380
|
subject: msg.subject,
|
|
1965
2381
|
}, "Event handler failed");
|
|
@@ -1968,6 +2384,31 @@ _Trellis_log = new WeakMap(), _Trellis_tasks = new WeakMap(), _Trellis_hasExplic
|
|
|
1968
2384
|
});
|
|
1969
2385
|
__classPrivateFieldGet(this, _Trellis_tasks, "f").add(`event:${event}:${(0, ulid_1.ulid)()}`, task);
|
|
1970
2386
|
return (0, result_1.ok)(undefined);
|
|
2387
|
+
}, _Trellis_invokeEventHandler = async function _Trellis_invokeEventHandler(args) {
|
|
2388
|
+
const annotation = {
|
|
2389
|
+
event: String(args.event),
|
|
2390
|
+
service: this.name,
|
|
2391
|
+
contractId: this.contractId,
|
|
2392
|
+
contractDigest: this.contractDigest,
|
|
2393
|
+
traceId: traceIdFromTraceparent(args.message.headers?.get("traceparent")),
|
|
2394
|
+
};
|
|
2395
|
+
try {
|
|
2396
|
+
const result = await Promise.resolve(args.fn(args.payload, createEventListenerContext({
|
|
2397
|
+
payload: args.payload,
|
|
2398
|
+
subject: args.message.subject,
|
|
2399
|
+
mode: args.mode,
|
|
2400
|
+
...(args.group ? { group: args.group } : {}),
|
|
2401
|
+
message: args.message,
|
|
2402
|
+
})));
|
|
2403
|
+
const outcome = isResultLike(result) ? result.take() : result;
|
|
2404
|
+
if ((0, result_1.isErr)(outcome)) {
|
|
2405
|
+
return (0, result_1.err)(annotateHandlerBoundaryError(outcome.error, annotation));
|
|
2406
|
+
}
|
|
2407
|
+
return (0, result_1.ok)(undefined);
|
|
2408
|
+
}
|
|
2409
|
+
catch (cause) {
|
|
2410
|
+
return (0, result_1.err)(annotateHandlerBoundaryError(cause, annotation));
|
|
2411
|
+
}
|
|
1971
2412
|
}, _Trellis_resolveEventConsumerGroup = function _Trellis_resolveEventConsumerGroup(event, opts) {
|
|
1972
2413
|
const metadata = __classPrivateFieldGet(this, _Trellis_eventConsumers, "f").metadata;
|
|
1973
2414
|
const bindings = __classPrivateFieldGet(this, _Trellis_eventConsumers, "f").bindings ?? {};
|
|
@@ -2093,15 +2534,17 @@ _Trellis_log = new WeakMap(), _Trellis_tasks = new WeakMap(), _Trellis_hasExplic
|
|
|
2093
2534
|
msg.term();
|
|
2094
2535
|
continue;
|
|
2095
2536
|
}
|
|
2096
|
-
const handlerResult = await
|
|
2537
|
+
const handlerResult = await __classPrivateFieldGet(this, _Trellis_instances, "m", _Trellis_invokeEventHandler).call(this, {
|
|
2538
|
+
event,
|
|
2097
2539
|
payload: m,
|
|
2098
|
-
subject: msg.subject,
|
|
2099
2540
|
mode: "durable",
|
|
2100
2541
|
message: msg,
|
|
2101
|
-
|
|
2102
|
-
|
|
2542
|
+
fn,
|
|
2543
|
+
});
|
|
2544
|
+
const handlerValue = handlerResult.take();
|
|
2545
|
+
if ((0, result_1.isErr)(handlerValue)) {
|
|
2103
2546
|
__classPrivateFieldGet(this, _Trellis_log, "f").error({
|
|
2104
|
-
error:
|
|
2547
|
+
error: handlerValue.error.toSerializable(),
|
|
2105
2548
|
event,
|
|
2106
2549
|
subject: msg.subject,
|
|
2107
2550
|
}, "Event handler failed");
|
|
@@ -2130,20 +2573,34 @@ _Trellis_log = new WeakMap(), _Trellis_tasks = new WeakMap(), _Trellis_hasExplic
|
|
|
2130
2573
|
const eventPayload = parsedEvent.take();
|
|
2131
2574
|
if ((0, result_1.isErr)(eventPayload)) {
|
|
2132
2575
|
__classPrivateFieldGet(this, _Trellis_log, "f").error({ error: eventPayload.error }, "Event validation failed");
|
|
2576
|
+
recordRuntimeError(eventPayload.error, {
|
|
2577
|
+
surface: "event",
|
|
2578
|
+
direction: "consumer",
|
|
2579
|
+
operation: String(registration.event),
|
|
2580
|
+
phase: "input_validation",
|
|
2581
|
+
});
|
|
2133
2582
|
msg.term();
|
|
2134
2583
|
failed = true;
|
|
2135
2584
|
break;
|
|
2136
2585
|
}
|
|
2137
|
-
const handlerResult = await
|
|
2586
|
+
const handlerResult = await __classPrivateFieldGet(this, _Trellis_instances, "m", _Trellis_invokeEventHandler).call(this, {
|
|
2587
|
+
event: registration.event,
|
|
2138
2588
|
payload: eventPayload,
|
|
2139
|
-
subject: msg.subject,
|
|
2140
2589
|
mode: "durable",
|
|
2141
2590
|
group,
|
|
2142
2591
|
message: msg,
|
|
2143
|
-
|
|
2144
|
-
|
|
2592
|
+
fn: registration.fn,
|
|
2593
|
+
});
|
|
2594
|
+
const handlerValue = handlerResult.take();
|
|
2595
|
+
if ((0, result_1.isErr)(handlerValue)) {
|
|
2596
|
+
recordRuntimeError(handlerValue.error, {
|
|
2597
|
+
surface: "event",
|
|
2598
|
+
direction: "consumer",
|
|
2599
|
+
operation: String(registration.event),
|
|
2600
|
+
phase: "handler_result",
|
|
2601
|
+
});
|
|
2145
2602
|
__classPrivateFieldGet(this, _Trellis_log, "f").error({
|
|
2146
|
-
error:
|
|
2603
|
+
error: handlerValue.error.toSerializable(),
|
|
2147
2604
|
event: registration.event,
|
|
2148
2605
|
subject: msg.subject,
|
|
2149
2606
|
}, "Event handler failed");
|
|
@@ -2217,8 +2674,8 @@ _Trellis_log = new WeakMap(), _Trellis_tasks = new WeakMap(), _Trellis_hasExplic
|
|
|
2217
2674
|
}));
|
|
2218
2675
|
}, _Trellis_requestJson = function _Trellis_requestJson(subject, body) {
|
|
2219
2676
|
return result_1.AsyncResult.from((async () => {
|
|
2220
|
-
const span = (0,
|
|
2221
|
-
return await (0,
|
|
2677
|
+
const span = (0, mod_js_2.startClientSpan)(subject, subject);
|
|
2678
|
+
return await (0, mod_js_2.withSpanAsync)(span, async () => {
|
|
2222
2679
|
try {
|
|
2223
2680
|
const payload = JSON.stringify(body);
|
|
2224
2681
|
const authHeaders = await __classPrivateFieldGet(this, _Trellis_instances, "m", _Trellis_createProof).call(this, subject, payload);
|
|
@@ -2227,7 +2684,7 @@ _Trellis_log = new WeakMap(), _Trellis_tasks = new WeakMap(), _Trellis_hasExplic
|
|
|
2227
2684
|
headers.set("proof", authHeaders.proof);
|
|
2228
2685
|
headers.set("iat", String(authHeaders.iat));
|
|
2229
2686
|
headers.set("request-id", authHeaders.requestId);
|
|
2230
|
-
(0,
|
|
2687
|
+
(0, mod_js_2.injectTraceContext)((0, mod_js_2.createNatsHeaderCarrier)(headers), span);
|
|
2231
2688
|
const response = (await __classPrivateFieldGet(this, _Trellis_instances, "m", _Trellis_requestMessageWithRetry).call(this, {
|
|
2232
2689
|
subject,
|
|
2233
2690
|
payload,
|
|
@@ -2236,9 +2693,15 @@ _Trellis_log = new WeakMap(), _Trellis_tasks = new WeakMap(), _Trellis_hasExplic
|
|
|
2236
2693
|
})).take();
|
|
2237
2694
|
if ((0, result_1.isErr)(response)) {
|
|
2238
2695
|
span.setStatus({
|
|
2239
|
-
code:
|
|
2696
|
+
code: mod_js_2.SpanStatusCode.ERROR,
|
|
2240
2697
|
message: response.error.message,
|
|
2241
2698
|
});
|
|
2699
|
+
recordRuntimeError(response.error, {
|
|
2700
|
+
surface: "operation",
|
|
2701
|
+
direction: "client",
|
|
2702
|
+
operation: "requestJson",
|
|
2703
|
+
phase: "request_send",
|
|
2704
|
+
});
|
|
2242
2705
|
return response;
|
|
2243
2706
|
}
|
|
2244
2707
|
const json = safeJson(response).take();
|
|
@@ -2251,21 +2714,33 @@ _Trellis_log = new WeakMap(), _Trellis_tasks = new WeakMap(), _Trellis_hasExplic
|
|
|
2251
2714
|
context: { subject },
|
|
2252
2715
|
});
|
|
2253
2716
|
span.setStatus({
|
|
2254
|
-
code:
|
|
2717
|
+
code: mod_js_2.SpanStatusCode.ERROR,
|
|
2255
2718
|
message: error.message,
|
|
2256
2719
|
});
|
|
2720
|
+
recordRuntimeError(error, {
|
|
2721
|
+
surface: "operation",
|
|
2722
|
+
direction: "client",
|
|
2723
|
+
operation: "requestJson",
|
|
2724
|
+
phase: "response_decoding",
|
|
2725
|
+
});
|
|
2257
2726
|
return (0, result_1.err)(error);
|
|
2258
2727
|
}
|
|
2259
|
-
span.setStatus({ code:
|
|
2728
|
+
span.setStatus({ code: mod_js_2.SpanStatusCode.OK });
|
|
2260
2729
|
return (0, result_1.ok)(json);
|
|
2261
2730
|
}
|
|
2262
2731
|
catch (cause) {
|
|
2263
2732
|
const error = new index_js_1.UnexpectedError({ cause });
|
|
2264
2733
|
span.setStatus({
|
|
2265
|
-
code:
|
|
2734
|
+
code: mod_js_2.SpanStatusCode.ERROR,
|
|
2266
2735
|
message: error.message,
|
|
2267
2736
|
});
|
|
2268
2737
|
span.recordException(error);
|
|
2738
|
+
recordRuntimeError(error, {
|
|
2739
|
+
surface: "operation",
|
|
2740
|
+
direction: "client",
|
|
2741
|
+
operation: "requestJson",
|
|
2742
|
+
phase: "unexpected",
|
|
2743
|
+
});
|
|
2269
2744
|
return (0, result_1.err)(error);
|
|
2270
2745
|
}
|
|
2271
2746
|
finally {
|
|
@@ -2293,35 +2768,56 @@ _Trellis_log = new WeakMap(), _Trellis_tasks = new WeakMap(), _Trellis_hasExplic
|
|
|
2293
2768
|
}
|
|
2294
2769
|
catch (cause) {
|
|
2295
2770
|
sub.unsubscribe();
|
|
2296
|
-
|
|
2771
|
+
const error = createTransportError({
|
|
2297
2772
|
code: "trellis.watch.failed",
|
|
2298
2773
|
message: "Trellis could not start the operation watch.",
|
|
2299
2774
|
hint: "Retry watching the operation. If it keeps failing, reconnect to Trellis and try again.",
|
|
2300
2775
|
cause,
|
|
2301
2776
|
context: { subject },
|
|
2302
|
-
})
|
|
2777
|
+
});
|
|
2778
|
+
recordRuntimeError(error, {
|
|
2779
|
+
surface: "operation",
|
|
2780
|
+
direction: "client",
|
|
2781
|
+
operation: "watchJson",
|
|
2782
|
+
phase: "request_send",
|
|
2783
|
+
});
|
|
2784
|
+
return (0, result_1.err)(error);
|
|
2303
2785
|
}
|
|
2304
2786
|
return (0, result_1.ok)((async function* () {
|
|
2305
2787
|
try {
|
|
2306
2788
|
for await (const msg of sub) {
|
|
2307
2789
|
if (msg.headers?.get("status") === "error") {
|
|
2308
|
-
|
|
2790
|
+
const error = createTransportError({
|
|
2309
2791
|
code: "trellis.watch.failed",
|
|
2310
2792
|
message: "Trellis stopped the operation watch.",
|
|
2311
2793
|
hint: "Retry watching the operation. If it keeps happening, reconnect to Trellis and try again.",
|
|
2312
2794
|
context: { subject, frame: msg.string() },
|
|
2313
|
-
})
|
|
2795
|
+
});
|
|
2796
|
+
recordRuntimeError(error, {
|
|
2797
|
+
surface: "operation",
|
|
2798
|
+
direction: "client",
|
|
2799
|
+
operation: "watchJson",
|
|
2800
|
+
phase: "remote_error",
|
|
2801
|
+
});
|
|
2802
|
+
yield (0, result_1.err)(error);
|
|
2314
2803
|
continue;
|
|
2315
2804
|
}
|
|
2316
2805
|
const json = safeJson(msg).take();
|
|
2317
2806
|
if ((0, result_1.isErr)(json)) {
|
|
2318
|
-
|
|
2807
|
+
const error = createTransportError({
|
|
2319
2808
|
code: "trellis.watch.invalid_response",
|
|
2320
2809
|
message: "Trellis returned an invalid watch update.",
|
|
2321
2810
|
hint: "Retry watching the operation. If it keeps happening, reconnect to Trellis and try again.",
|
|
2322
2811
|
cause: json.error.cause,
|
|
2323
2812
|
context: { subject },
|
|
2324
|
-
})
|
|
2813
|
+
});
|
|
2814
|
+
recordRuntimeError(error, {
|
|
2815
|
+
surface: "operation",
|
|
2816
|
+
direction: "client",
|
|
2817
|
+
operation: "watchJson",
|
|
2818
|
+
phase: "response_decoding",
|
|
2819
|
+
});
|
|
2820
|
+
yield (0, result_1.err)(error);
|
|
2325
2821
|
continue;
|
|
2326
2822
|
}
|
|
2327
2823
|
yield (0, result_1.ok)(json);
|