@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.
Files changed (131) hide show
  1. package/esm/client.d.ts +2 -0
  2. package/esm/client.d.ts.map +1 -1
  3. package/esm/client.js +2 -0
  4. package/esm/client_connect.d.ts +3 -2
  5. package/esm/client_connect.d.ts.map +1 -1
  6. package/esm/client_connect.js +4 -1
  7. package/esm/errors/TrellisError.d.ts +3 -3
  8. package/esm/errors/TrellisError.js +3 -3
  9. package/esm/server/health.d.ts.map +1 -1
  10. package/esm/server/health.js +34 -3
  11. package/esm/server/internal_jobs/job-manager.d.ts.map +1 -1
  12. package/esm/server/internal_jobs/job-manager.js +32 -1
  13. package/esm/server/runtime.d.ts +3 -0
  14. package/esm/server/runtime.d.ts.map +1 -1
  15. package/esm/server/service.d.ts +15 -0
  16. package/esm/server/service.d.ts.map +1 -1
  17. package/esm/server/service.js +41 -3
  18. package/esm/server.d.ts.map +1 -1
  19. package/esm/server.js +99 -10
  20. package/esm/service/deno.d.ts +1 -1
  21. package/esm/service/deno.d.ts.map +1 -1
  22. package/esm/service/mod.d.ts +1 -1
  23. package/esm/service/mod.d.ts.map +1 -1
  24. package/esm/service/node.d.ts +1 -1
  25. package/esm/service/node.d.ts.map +1 -1
  26. package/esm/service/outbox_inbox.d.ts.map +1 -1
  27. package/esm/service/outbox_inbox.js +14 -0
  28. package/esm/telemetry/core.d.ts.map +1 -1
  29. package/esm/telemetry/core.js +1 -1
  30. package/esm/telemetry/env.d.ts.map +1 -1
  31. package/esm/telemetry/env.js +6 -1
  32. package/esm/telemetry/init.d.ts +3 -0
  33. package/esm/telemetry/init.d.ts.map +1 -0
  34. package/esm/telemetry/init.js +7 -0
  35. package/esm/telemetry/metrics.d.ts +34 -0
  36. package/esm/telemetry/metrics.d.ts.map +1 -0
  37. package/esm/telemetry/metrics.js +181 -0
  38. package/esm/telemetry/mod.d.ts +3 -0
  39. package/esm/telemetry/mod.d.ts.map +1 -1
  40. package/esm/telemetry/mod.js +2 -0
  41. package/esm/telemetry/runtime.d.ts +2 -0
  42. package/esm/telemetry/runtime.d.ts.map +1 -0
  43. package/esm/telemetry/runtime.js +134 -0
  44. package/esm/telemetry.d.ts +3 -0
  45. package/esm/telemetry.d.ts.map +1 -0
  46. package/esm/telemetry.js +2 -0
  47. package/esm/transfer.d.ts.map +1 -1
  48. package/esm/transfer.js +27 -16
  49. package/esm/trellis.d.ts +28 -4
  50. package/esm/trellis.d.ts.map +1 -1
  51. package/esm/trellis.js +575 -80
  52. package/package.json +7 -5
  53. package/script/client.d.ts +2 -0
  54. package/script/client.d.ts.map +1 -1
  55. package/script/client.js +2 -0
  56. package/script/client_connect.d.ts +3 -2
  57. package/script/client_connect.d.ts.map +1 -1
  58. package/script/client_connect.js +4 -1
  59. package/script/errors/TrellisError.d.ts +3 -3
  60. package/script/errors/TrellisError.js +3 -3
  61. package/script/server/health.d.ts.map +1 -1
  62. package/script/server/health.js +34 -3
  63. package/script/server/internal_jobs/job-manager.d.ts.map +1 -1
  64. package/script/server/internal_jobs/job-manager.js +32 -1
  65. package/script/server/runtime.d.ts +3 -0
  66. package/script/server/runtime.d.ts.map +1 -1
  67. package/script/server/service.d.ts +15 -0
  68. package/script/server/service.d.ts.map +1 -1
  69. package/script/server/service.js +40 -2
  70. package/script/server.d.ts.map +1 -1
  71. package/script/server.js +98 -9
  72. package/script/service/deno.d.ts +1 -1
  73. package/script/service/deno.d.ts.map +1 -1
  74. package/script/service/mod.d.ts +1 -1
  75. package/script/service/mod.d.ts.map +1 -1
  76. package/script/service/node.d.ts +1 -1
  77. package/script/service/node.d.ts.map +1 -1
  78. package/script/service/outbox_inbox.d.ts.map +1 -1
  79. package/script/service/outbox_inbox.js +14 -0
  80. package/script/telemetry/core.d.ts.map +1 -1
  81. package/script/telemetry/core.js +1 -1
  82. package/script/telemetry/env.d.ts.map +1 -1
  83. package/script/telemetry/env.js +6 -1
  84. package/script/telemetry/init.d.ts +3 -0
  85. package/script/telemetry/init.d.ts.map +1 -0
  86. package/script/telemetry/init.js +10 -0
  87. package/script/telemetry/metrics.d.ts +34 -0
  88. package/script/telemetry/metrics.d.ts.map +1 -0
  89. package/script/telemetry/metrics.js +186 -0
  90. package/script/telemetry/mod.d.ts +3 -0
  91. package/script/telemetry/mod.d.ts.map +1 -1
  92. package/script/telemetry/mod.js +7 -1
  93. package/script/telemetry/runtime.d.ts +2 -0
  94. package/script/telemetry/runtime.d.ts.map +1 -0
  95. package/script/telemetry/runtime.js +137 -0
  96. package/script/telemetry.d.ts +3 -0
  97. package/script/telemetry.d.ts.map +1 -0
  98. package/script/telemetry.js +18 -0
  99. package/script/transfer.d.ts.map +1 -1
  100. package/script/transfer.js +28 -17
  101. package/script/trellis.d.ts +28 -4
  102. package/script/trellis.d.ts.map +1 -1
  103. package/script/trellis.js +606 -110
  104. package/src/client.ts +4 -0
  105. package/src/client_connect.ts +11 -9
  106. package/src/errors/TrellisError.ts +4 -4
  107. package/src/server/health.ts +41 -3
  108. package/src/server/internal_jobs/job-manager.ts +35 -5
  109. package/src/server/runtime.ts +4 -0
  110. package/src/server/service.ts +75 -3
  111. package/src/server.ts +124 -14
  112. package/src/service/deno.ts +1 -0
  113. package/src/service/mod.ts +1 -0
  114. package/src/service/node.ts +1 -0
  115. package/src/service/outbox_inbox.ts +14 -0
  116. package/src/telemetry/core.ts +1 -1
  117. package/src/telemetry/env.ts +5 -1
  118. package/src/telemetry/init.ts +8 -0
  119. package/src/telemetry/metrics.ts +294 -0
  120. package/src/telemetry/mod.ts +7 -0
  121. package/src/telemetry/runtime.ts +218 -0
  122. package/src/telemetry.ts +2 -0
  123. package/src/transfer.ts +69 -30
  124. package/src/trellis.ts +652 -141
  125. package/esm/tracing.d.ts +0 -5
  126. package/esm/tracing.d.ts.map +0 -1
  127. package/esm/tracing.js +0 -8
  128. package/script/tracing.d.ts +0 -5
  129. package/script/tracing.d.ts.map +0 -1
  130. package/script/tracing.js +0 -27
  131. 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 tracing_js_1 = require("./tracing.js");
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
- return (0, result_1.err)(new index_js_1.UnexpectedError({
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
- return (0, result_1.err)(new index_js_1.UnexpectedError({ cause: msg.error }));
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, tracing_js_1.injectTraceContext)((0, tracing_js_1.createNatsHeaderCarrier)(headers));
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
- return (0, result_1.err)(new index_js_1.UnexpectedError({ cause, context: { event: event.toString() } }));
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
- return (0, result_1.err)(new index_js_1.UnexpectedError({ cause, context: { event: event.event } }));
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, tracing_js_1.startClientSpan)(method, subject);
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, tracing_js_1.injectTraceContext)((0, tracing_js_1.createNatsHeaderCarrier)(headers), span);
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
- return (0, result_1.err)(requestFailedTransportError({
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
- return (0, result_1.err)(requestFailedTransportError({
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
- return (0, result_1.err)(requestFailedTransportError({
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, tracing_js_1.withSpanAsync)(span, async () => {
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: tracing_js_1.SpanStatusCode.ERROR,
1439
+ code: mod_js_2.SpanStatusCode.ERROR,
1304
1440
  message: value.error.message,
1305
1441
  });
1306
1442
  }
1307
1443
  else {
1308
- span.setStatus({ code: tracing_js_1.SpanStatusCode.OK });
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: tracing_js_1.SpanStatusCode.ERROR,
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, tracing_js_1.injectTraceContext)((0, tracing_js_1.createNatsHeaderCarrier)(headers));
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
- return (0, result_1.err)(createTransportError({
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
- return (0, result_1.err)(createTransportError({
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
- return (0, result_1.err)(createTransportError({
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
- return (0, result_1.err)(createTransportError({
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
- throw createTransportError({
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
- throw createTransportError({
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 instanceof result_1.BaseError
1547
- ? cause
1548
- : new index_js_1.UnexpectedError({ cause });
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
- return (0, result_1.err)(new index_js_1.UnexpectedError({
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
- return (0, result_1.err)(new index_js_1.UnexpectedError({
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, tracing_js_1.extractTraceContext)((0, tracing_js_1.createNatsHeaderCarrier)({
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, tracing_js_1.startServerSpan)(method, msg.subject, parentContext);
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, tracing_js_1.withSpanAsync)(span, async () => {
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: tracing_js_1.SpanStatusCode.ERROR,
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: tracing_js_1.SpanStatusCode.ERROR,
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: tracing_js_1.SpanStatusCode.ERROR,
2010
+ code: mod_js_2.SpanStatusCode.ERROR,
1699
2011
  message: "Missing session-key",
1700
2012
  });
1701
- return (0, result_1.err)(new index_js_1.AuthError({ reason: "missing_session_key" }));
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: tracing_js_1.SpanStatusCode.ERROR,
2025
+ code: mod_js_2.SpanStatusCode.ERROR,
1707
2026
  message: "Missing proof",
1708
2027
  });
1709
- return (0, result_1.err)(new index_js_1.AuthError({ reason: "missing_proof" }));
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
- return (0, result_1.err)(new index_js_1.AuthError({ reason: "invalid_signature" }));
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: tracing_js_1.SpanStatusCode.ERROR,
2062
+ code: mod_js_2.SpanStatusCode.ERROR,
1730
2063
  message: "Invalid signature",
1731
2064
  });
1732
- return (0, result_1.err)(new index_js_1.AuthError({
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
- return (0, result_1.err)(new index_js_1.UnexpectedError({
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: tracing_js_1.SpanStatusCode.ERROR,
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
- return (0, result_1.err)(new index_js_1.UnexpectedError({ cause: auth }));
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: tracing_js_1.SpanStatusCode.ERROR,
2145
+ code: mod_js_2.SpanStatusCode.ERROR,
1786
2146
  message: "Insufficient permissions",
1787
2147
  });
1788
- return (0, result_1.err)(new index_js_1.AuthError({
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: tracing_js_1.SpanStatusCode.ERROR,
2166
+ code: mod_js_2.SpanStatusCode.ERROR,
1800
2167
  message: "Reply subject mismatch",
1801
2168
  });
1802
- return (0, result_1.err)(new index_js_1.AuthError({
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.withContext({ method });
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: tracing_js_1.SpanStatusCode.ERROR,
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 handlerError = handlerOutcome.error;
1852
- const error = handlerError instanceof result_1.BaseError &&
1853
- !(handlerError instanceof RemoteError_js_1.RemoteError)
1854
- ? handlerError
1855
- : new index_js_1.UnexpectedError({ cause: handlerError });
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: tracing_js_1.SpanStatusCode.ERROR,
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: tracing_js_1.SpanStatusCode.ERROR,
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: tracing_js_1.SpanStatusCode.OK });
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 result_1.AsyncResult.lift(fn(m, createEventListenerContext({
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
- if (handlerResult.isErr()) {
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: handlerResult.error.toSerializable(),
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 result_1.AsyncResult.lift(fn(m, createEventListenerContext({
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
- if (handlerResult.isErr()) {
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: handlerResult.error.toSerializable(),
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 result_1.AsyncResult.lift(registration.fn(eventPayload, createEventListenerContext({
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
- if (handlerResult.isErr()) {
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: handlerResult.error.toSerializable(),
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, tracing_js_1.startClientSpan)(subject, subject);
2221
- return await (0, tracing_js_1.withSpanAsync)(span, async () => {
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, tracing_js_1.injectTraceContext)((0, tracing_js_1.createNatsHeaderCarrier)(headers), span);
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: tracing_js_1.SpanStatusCode.ERROR,
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: tracing_js_1.SpanStatusCode.ERROR,
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: tracing_js_1.SpanStatusCode.OK });
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: tracing_js_1.SpanStatusCode.ERROR,
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
- return (0, result_1.err)(createTransportError({
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
- yield (0, result_1.err)(createTransportError({
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
- yield (0, result_1.err)(createTransportError({
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);