@qlever-llc/trellis 0.10.11 → 0.10.13

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 (124) hide show
  1. package/esm/contract_support/mod.d.ts +1 -0
  2. package/esm/contract_support/mod.d.ts.map +1 -1
  3. package/esm/contract_support/mod.js +1 -0
  4. package/esm/contract_support/schema_pointers.d.ts +6 -0
  5. package/esm/contract_support/schema_pointers.d.ts.map +1 -1
  6. package/esm/contract_support/schema_pointers.js +59 -7
  7. package/esm/errors/TrellisError.d.ts +3 -3
  8. package/esm/errors/TrellisError.js +3 -3
  9. package/esm/server/internal_jobs/job-manager.d.ts.map +1 -1
  10. package/esm/server/internal_jobs/job-manager.js +32 -1
  11. package/esm/server/runtime.d.ts +3 -0
  12. package/esm/server/runtime.d.ts.map +1 -1
  13. package/esm/server/service.d.ts +15 -0
  14. package/esm/server/service.d.ts.map +1 -1
  15. package/esm/server/service.js +8 -0
  16. package/esm/server.d.ts.map +1 -1
  17. package/esm/server.js +54 -6
  18. package/esm/service/deno.d.ts +1 -1
  19. package/esm/service/deno.d.ts.map +1 -1
  20. package/esm/service/mod.d.ts +1 -1
  21. package/esm/service/mod.d.ts.map +1 -1
  22. package/esm/service/node.d.ts +1 -1
  23. package/esm/service/node.d.ts.map +1 -1
  24. package/esm/service/outbox_inbox.d.ts.map +1 -1
  25. package/esm/service/outbox_inbox.js +14 -0
  26. package/esm/telemetry/core.d.ts.map +1 -1
  27. package/esm/telemetry/core.js +1 -1
  28. package/esm/telemetry/env.d.ts.map +1 -1
  29. package/esm/telemetry/env.js +6 -1
  30. package/esm/telemetry/init.d.ts +3 -0
  31. package/esm/telemetry/init.d.ts.map +1 -0
  32. package/esm/telemetry/init.js +7 -0
  33. package/esm/telemetry/metrics.d.ts +34 -0
  34. package/esm/telemetry/metrics.d.ts.map +1 -0
  35. package/esm/telemetry/metrics.js +181 -0
  36. package/esm/telemetry/mod.d.ts +3 -0
  37. package/esm/telemetry/mod.d.ts.map +1 -1
  38. package/esm/telemetry/mod.js +2 -0
  39. package/esm/telemetry/runtime.d.ts +2 -0
  40. package/esm/telemetry/runtime.d.ts.map +1 -0
  41. package/esm/telemetry/runtime.js +134 -0
  42. package/esm/telemetry.d.ts +3 -0
  43. package/esm/telemetry.d.ts.map +1 -0
  44. package/esm/telemetry.js +2 -0
  45. package/esm/transfer.d.ts.map +1 -1
  46. package/esm/transfer.js +27 -16
  47. package/esm/trellis.d.ts.map +1 -1
  48. package/esm/trellis.js +460 -56
  49. package/package.json +7 -5
  50. package/script/contract_support/mod.d.ts +1 -0
  51. package/script/contract_support/mod.d.ts.map +1 -1
  52. package/script/contract_support/mod.js +4 -1
  53. package/script/contract_support/schema_pointers.d.ts +6 -0
  54. package/script/contract_support/schema_pointers.d.ts.map +1 -1
  55. package/script/contract_support/schema_pointers.js +59 -7
  56. package/script/errors/TrellisError.d.ts +3 -3
  57. package/script/errors/TrellisError.js +3 -3
  58. package/script/server/internal_jobs/job-manager.d.ts.map +1 -1
  59. package/script/server/internal_jobs/job-manager.js +32 -1
  60. package/script/server/runtime.d.ts +3 -0
  61. package/script/server/runtime.d.ts.map +1 -1
  62. package/script/server/service.d.ts +15 -0
  63. package/script/server/service.d.ts.map +1 -1
  64. package/script/server/service.js +8 -0
  65. package/script/server.d.ts.map +1 -1
  66. package/script/server.js +54 -6
  67. package/script/service/deno.d.ts +1 -1
  68. package/script/service/deno.d.ts.map +1 -1
  69. package/script/service/mod.d.ts +1 -1
  70. package/script/service/mod.d.ts.map +1 -1
  71. package/script/service/node.d.ts +1 -1
  72. package/script/service/node.d.ts.map +1 -1
  73. package/script/service/outbox_inbox.d.ts.map +1 -1
  74. package/script/service/outbox_inbox.js +14 -0
  75. package/script/telemetry/core.d.ts.map +1 -1
  76. package/script/telemetry/core.js +1 -1
  77. package/script/telemetry/env.d.ts.map +1 -1
  78. package/script/telemetry/env.js +6 -1
  79. package/script/telemetry/init.d.ts +3 -0
  80. package/script/telemetry/init.d.ts.map +1 -0
  81. package/script/telemetry/init.js +10 -0
  82. package/script/telemetry/metrics.d.ts +34 -0
  83. package/script/telemetry/metrics.d.ts.map +1 -0
  84. package/script/telemetry/metrics.js +186 -0
  85. package/script/telemetry/mod.d.ts +3 -0
  86. package/script/telemetry/mod.d.ts.map +1 -1
  87. package/script/telemetry/mod.js +7 -1
  88. package/script/telemetry/runtime.d.ts +2 -0
  89. package/script/telemetry/runtime.d.ts.map +1 -0
  90. package/script/telemetry/runtime.js +137 -0
  91. package/script/telemetry.d.ts +3 -0
  92. package/script/telemetry.d.ts.map +1 -0
  93. package/script/telemetry.js +18 -0
  94. package/script/transfer.d.ts.map +1 -1
  95. package/script/transfer.js +28 -17
  96. package/script/trellis.d.ts.map +1 -1
  97. package/script/trellis.js +490 -86
  98. package/src/contract_support/mod.ts +4 -0
  99. package/src/contract_support/schema_pointers.ts +80 -7
  100. package/src/errors/TrellisError.ts +4 -4
  101. package/src/server/internal_jobs/job-manager.ts +35 -5
  102. package/src/server/runtime.ts +4 -0
  103. package/src/server/service.ts +27 -0
  104. package/src/server.ts +66 -11
  105. package/src/service/deno.ts +1 -0
  106. package/src/service/mod.ts +1 -0
  107. package/src/service/node.ts +1 -0
  108. package/src/service/outbox_inbox.ts +14 -0
  109. package/src/telemetry/core.ts +1 -1
  110. package/src/telemetry/env.ts +5 -1
  111. package/src/telemetry/init.ts +8 -0
  112. package/src/telemetry/metrics.ts +294 -0
  113. package/src/telemetry/mod.ts +7 -0
  114. package/src/telemetry/runtime.ts +218 -0
  115. package/src/telemetry.ts +2 -0
  116. package/src/transfer.ts +69 -30
  117. package/src/trellis.ts +487 -88
  118. package/esm/tracing.d.ts +0 -5
  119. package/esm/tracing.d.ts.map +0 -1
  120. package/esm/tracing.js +0 -8
  121. package/script/tracing.d.ts +0 -5
  122. package/script/tracing.d.ts.map +0 -1
  123. package/script/tracing.js +0 -27
  124. package/src/tracing.ts +0 -28
package/script/trellis.js CHANGED
@@ -29,7 +29,7 @@ const jetstream_1 = require("@nats-io/jetstream");
29
29
  const nats_core_1 = require("@nats-io/nats-core");
30
30
  const mod_js_1 = require("./contract_support/mod.js");
31
31
  const result_1 = require("@qlever-llc/result");
32
- const tracing_js_1 = require("./tracing.js");
32
+ const mod_js_2 = require("./telemetry/mod.js");
33
33
  const typebox_1 = require("typebox");
34
34
  const value_1 = require("typebox/value");
35
35
  const ulid_1 = require("ulid");
@@ -220,6 +220,12 @@ function annotateHandlerBoundaryError(cause, context) {
220
220
  error.withTraceId(context.traceId);
221
221
  return error;
222
222
  }
223
+ function recordRuntimeError(error, attributes) {
224
+ (0, mod_js_2.recordTrellisError)(error, {
225
+ messagingSystem: "nats",
226
+ ...attributes,
227
+ });
228
+ }
223
229
  const DurableOperationSignalSchema = typebox_1.Type.Object({
224
230
  operationId: typebox_1.Type.String(),
225
231
  sequence: typebox_1.Type.Number(),
@@ -950,14 +956,27 @@ class Trellis {
950
956
  const eventName = event;
951
957
  const ctx = this.api["events"][eventName];
952
958
  if (!ctx) {
953
- return (0, result_1.err)(new index_js_1.UnexpectedError({
959
+ const error = new index_js_1.UnexpectedError({
954
960
  cause: __classPrivateFieldGet(this, _Trellis_instances, "m", _Trellis_unknownApiError).call(this, "event", event.toString()),
955
961
  context: { event: event.toString() },
956
- }));
962
+ });
963
+ recordRuntimeError(error, {
964
+ surface: "event",
965
+ direction: "publisher",
966
+ operation: event,
967
+ phase: "prepare",
968
+ });
969
+ return (0, result_1.err)(error);
957
970
  }
958
971
  const subject = this.template(ctx.subject, data).take();
959
972
  if ((0, result_1.isErr)(subject)) {
960
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
+ });
961
980
  return subject;
962
981
  }
963
982
  const header = {
@@ -971,11 +990,18 @@ class Trellis {
971
990
  const msg = (0, codec_js_1.encodeSchema)(ctx.event, payload).take();
972
991
  if ((0, result_1.isErr)(msg)) {
973
992
  globals_js_1.logger.error({ err: msg.error }, "Failed to encode event.");
974
- 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);
975
1001
  }
976
1002
  const headers = (0, nats_core_1.headers)();
977
1003
  headers.set("Nats-Msg-Id", header.id);
978
- (0, tracing_js_1.injectTraceContext)((0, tracing_js_1.createNatsHeaderCarrier)(headers));
1004
+ (0, mod_js_2.injectTraceContext)((0, mod_js_2.createNatsHeaderCarrier)(headers));
979
1005
  const headerRecord = {};
980
1006
  for (const [key, value] of headers) {
981
1007
  headerRecord[key] = value.join(",");
@@ -989,7 +1015,17 @@ class Trellis {
989
1015
  }));
990
1016
  }
991
1017
  catch (cause) {
992
- 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);
993
1029
  }
994
1030
  }
995
1031
  /**
@@ -1008,7 +1044,17 @@ class Trellis {
1008
1044
  return (0, result_1.ok)(undefined);
1009
1045
  }
1010
1046
  catch (cause) {
1011
- 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);
1012
1058
  }
1013
1059
  })());
1014
1060
  }
@@ -1245,13 +1291,25 @@ _Trellis_log = new WeakMap(), _Trellis_tasks = new WeakMap(), _Trellis_hasExplic
1245
1291
  __classPrivateFieldGet(this, _Trellis_log, "f").trace({ method: String(method) }, `Calling ${method.toString()}.`);
1246
1292
  const msg = encodeRuntimeSchema(ctx.input, input).take();
1247
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
+ });
1248
1300
  return msg;
1249
1301
  }
1250
1302
  const subject = this.template(ctx.subject, input).take();
1251
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
+ });
1252
1310
  return subject;
1253
1311
  }
1254
- const span = (0, tracing_js_1.startClientSpan)(method, subject);
1312
+ const span = (0, mod_js_2.startClientSpan)(method, subject);
1255
1313
  const attempt = async () => {
1256
1314
  const authHeaders = await __classPrivateFieldGet(this, _Trellis_instances, "m", _Trellis_createProof).call(this, subject, msg);
1257
1315
  const headers = (0, nats_core_1.headers)();
@@ -1259,7 +1317,7 @@ _Trellis_log = new WeakMap(), _Trellis_tasks = new WeakMap(), _Trellis_hasExplic
1259
1317
  headers.set("proof", authHeaders.proof);
1260
1318
  headers.set("iat", String(authHeaders.iat));
1261
1319
  headers.set("request-id", authHeaders.requestId);
1262
- (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);
1263
1321
  const msgResult = await __classPrivateFieldGet(this, _Trellis_instances, "m", _Trellis_requestMessageWithRetry).call(this, {
1264
1322
  method,
1265
1323
  subject,
@@ -1270,30 +1328,50 @@ _Trellis_log = new WeakMap(), _Trellis_tasks = new WeakMap(), _Trellis_hasExplic
1270
1328
  });
1271
1329
  const response = msgResult.take();
1272
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
+ });
1273
1337
  return response;
1274
1338
  }
1275
1339
  if (response.headers?.get("status") === "error") {
1276
1340
  const json = safeJson(response).take();
1277
1341
  if ((0, result_1.isErr)(json)) {
1278
- return (0, result_1.err)(requestFailedTransportError({
1342
+ const error = requestFailedTransportError({
1279
1343
  code: "trellis.request.invalid_response",
1280
1344
  message: "Trellis returned an invalid response.",
1281
1345
  hint: "Retry the request. If it keeps happening, check the Trellis capability handling this request.",
1282
1346
  method,
1283
1347
  subject,
1284
1348
  cause: json.error.cause,
1285
- }));
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);
1286
1357
  }
1287
1358
  const errorData = (0, codec_js_1.parse)(TrellisError_js_1.TrellisErrorDataSchema, json).take();
1288
1359
  if ((0, result_1.isErr)(errorData)) {
1289
- return (0, result_1.err)(requestFailedTransportError({
1360
+ const error = requestFailedTransportError({
1290
1361
  code: "trellis.request.invalid_response",
1291
1362
  message: "Trellis returned an invalid response.",
1292
1363
  hint: "Retry the request. If it keeps happening, check the Trellis capability handling this request.",
1293
1364
  method,
1294
1365
  subject,
1295
1366
  cause: errorData.error,
1296
- }));
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);
1297
1375
  }
1298
1376
  const declaredErrorTypes = Array.isArray(ctx.declaredErrorTypes)
1299
1377
  ? ctx.declaredErrorTypes.filter((value) => typeof value === "string")
@@ -1304,41 +1382,66 @@ _Trellis_log = new WeakMap(), _Trellis_tasks = new WeakMap(), _Trellis_hasExplic
1304
1382
  const reconstructed = reconstructDeclaredRpcError(declaredErrorTypes, runtimeErrors, errorData, json);
1305
1383
  if (reconstructed) {
1306
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
+ });
1307
1391
  return (0, result_1.err)(reconstructed);
1308
1392
  }
1309
1393
  const remoteError = new RemoteError_js_1.RemoteError({ error: errorData });
1310
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
+ });
1311
1401
  return (0, result_1.err)(remoteError);
1312
1402
  }
1313
1403
  const json = safeJson(response).take();
1314
1404
  if ((0, result_1.isErr)(json)) {
1315
- return (0, result_1.err)(requestFailedTransportError({
1405
+ const error = requestFailedTransportError({
1316
1406
  code: "trellis.request.invalid_response",
1317
1407
  message: "Trellis returned an invalid response.",
1318
1408
  hint: "Retry the request. If it keeps happening, check the Trellis capability handling this request.",
1319
1409
  method,
1320
1410
  subject,
1321
1411
  cause: json.error.cause,
1322
- }));
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);
1323
1420
  }
1324
1421
  const outputResult = parseRuntimeSchema(ctx.output, json).take();
1325
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
+ });
1326
1429
  return (0, result_1.err)(outputResult.error);
1327
1430
  }
1328
1431
  return (0, result_1.ok)(outputResult);
1329
1432
  };
1330
- return await (0, tracing_js_1.withSpanAsync)(span, async () => {
1433
+ return await (0, mod_js_2.withSpanAsync)(span, async () => {
1331
1434
  try {
1332
1435
  const result = await attempt();
1333
1436
  const value = result.take();
1334
1437
  if ((0, result_1.isErr)(value)) {
1335
1438
  span.setStatus({
1336
- code: tracing_js_1.SpanStatusCode.ERROR,
1439
+ code: mod_js_2.SpanStatusCode.ERROR,
1337
1440
  message: value.error.message,
1338
1441
  });
1339
1442
  }
1340
1443
  else {
1341
- span.setStatus({ code: tracing_js_1.SpanStatusCode.OK });
1444
+ span.setStatus({ code: mod_js_2.SpanStatusCode.OK });
1342
1445
  }
1343
1446
  return result;
1344
1447
  }
@@ -1347,10 +1450,16 @@ _Trellis_log = new WeakMap(), _Trellis_tasks = new WeakMap(), _Trellis_hasExplic
1347
1450
  ? cause
1348
1451
  : new index_js_1.UnexpectedError({ cause });
1349
1452
  span.setStatus({
1350
- code: tracing_js_1.SpanStatusCode.ERROR,
1453
+ code: mod_js_2.SpanStatusCode.ERROR,
1351
1454
  message: unexpected.message,
1352
1455
  });
1353
1456
  span.recordException(unexpected);
1457
+ recordRuntimeError(unexpected, {
1458
+ surface: "rpc",
1459
+ direction: "client",
1460
+ operation: method,
1461
+ phase: "unexpected",
1462
+ });
1354
1463
  return (0, result_1.err)(unexpected);
1355
1464
  }
1356
1465
  finally {
@@ -1419,18 +1528,32 @@ _Trellis_log = new WeakMap(), _Trellis_tasks = new WeakMap(), _Trellis_hasExplic
1419
1528
  }, _Trellis_subscribeFeed = function _Trellis_subscribeFeed(feed, descriptor, input, opts) {
1420
1529
  return result_1.AsyncResult.from((async () => {
1421
1530
  const payload = encodeRuntimeSchema(descriptor.input, input).take();
1422
- 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
+ });
1423
1538
  return payload;
1539
+ }
1424
1540
  const subject = this.template(descriptor.subject, input).take();
1425
- 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
+ });
1426
1548
  return subject;
1549
+ }
1427
1550
  const authHeaders = await __classPrivateFieldGet(this, _Trellis_instances, "m", _Trellis_createProof).call(this, subject, payload);
1428
1551
  const headers = (0, nats_core_1.headers)();
1429
1552
  headers.set("session-key", this.auth.sessionKey);
1430
1553
  headers.set("proof", authHeaders.proof);
1431
1554
  headers.set("iat", String(authHeaders.iat));
1432
1555
  headers.set("request-id", authHeaders.requestId);
1433
- (0, tracing_js_1.injectTraceContext)((0, tracing_js_1.createNatsHeaderCarrier)(headers));
1556
+ (0, mod_js_2.injectTraceContext)((0, mod_js_2.createNatsHeaderCarrier)(headers));
1434
1557
  const inbox = (0, nats_core_1.createInbox)(`_INBOX.${this.auth.sessionKey.slice(0, 16)}`);
1435
1558
  const sub = this.nats.subscribe(inbox);
1436
1559
  const iterator = sub[Symbol.asyncIterator]();
@@ -1443,13 +1566,20 @@ _Trellis_log = new WeakMap(), _Trellis_tasks = new WeakMap(), _Trellis_hasExplic
1443
1566
  catch (cause) {
1444
1567
  opts?.signal?.removeEventListener("abort", abort);
1445
1568
  sub.unsubscribe();
1446
- return (0, result_1.err)(createTransportError({
1569
+ const error = createTransportError({
1447
1570
  code: "trellis.feed.subscribe_failed",
1448
1571
  message: "Trellis could not subscribe to the feed.",
1449
1572
  hint: "Retry the subscription. If it keeps failing, check Trellis runtime health.",
1450
1573
  cause,
1451
1574
  context: { feed, subject },
1452
- }));
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);
1453
1583
  }
1454
1584
  let timeoutId;
1455
1585
  let abortHandler;
@@ -1475,7 +1605,7 @@ _Trellis_log = new WeakMap(), _Trellis_tasks = new WeakMap(), _Trellis_hasExplic
1475
1605
  if (firstFrame === "timeout" || firstFrame === "aborted") {
1476
1606
  opts?.signal?.removeEventListener("abort", abort);
1477
1607
  sub.unsubscribe();
1478
- return (0, result_1.err)(createTransportError({
1608
+ const error = createTransportError({
1479
1609
  code: firstFrame === "timeout"
1480
1610
  ? "trellis.feed.subscribe_timeout"
1481
1611
  : "trellis.feed.subscribe_aborted",
@@ -1486,28 +1616,49 @@ _Trellis_log = new WeakMap(), _Trellis_tasks = new WeakMap(), _Trellis_hasExplic
1486
1616
  ? "Check that the target service is running and has the current deployment digest, then retry."
1487
1617
  : "Retry the subscription if the feed is still needed.",
1488
1618
  context: { feed, subject },
1489
- }));
1619
+ });
1620
+ recordRuntimeError(error, {
1621
+ surface: "feed",
1622
+ direction: "client",
1623
+ operation: feed,
1624
+ phase: "handshake",
1625
+ });
1626
+ return (0, result_1.err)(error);
1490
1627
  }
1491
1628
  if (firstFrame.done) {
1492
1629
  opts?.signal?.removeEventListener("abort", abort);
1493
1630
  sub.unsubscribe();
1494
- return (0, result_1.err)(createTransportError({
1631
+ const error = createTransportError({
1495
1632
  code: "trellis.feed.subscribe_closed",
1496
1633
  message: "Trellis closed the feed before acknowledging it.",
1497
1634
  hint: "Retry the subscription. If it keeps failing, check Trellis runtime health.",
1498
1635
  context: { feed, subject },
1499
- }));
1636
+ });
1637
+ recordRuntimeError(error, {
1638
+ surface: "feed",
1639
+ direction: "client",
1640
+ operation: feed,
1641
+ phase: "handshake",
1642
+ });
1643
+ return (0, result_1.err)(error);
1500
1644
  }
1501
1645
  const firstMessage = firstFrame.value;
1502
1646
  if (firstMessage.headers?.get("status") === "error") {
1503
1647
  opts?.signal?.removeEventListener("abort", abort);
1504
1648
  sub.unsubscribe();
1505
- return (0, result_1.err)(createTransportError({
1649
+ const error = createTransportError({
1506
1650
  code: "trellis.feed.failed",
1507
1651
  message: "Trellis rejected the feed subscription.",
1508
1652
  hint: "Retry the subscription. If it keeps failing, check Trellis runtime health and permissions.",
1509
1653
  context: { feed, subject, frame: firstMessage.string() },
1510
- }));
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);
1511
1662
  }
1512
1663
  const firstEvent = firstMessage.headers?.get("feed-status") === "ready"
1513
1664
  ? undefined
@@ -1517,19 +1668,40 @@ _Trellis_log = new WeakMap(), _Trellis_tasks = new WeakMap(), _Trellis_hasExplic
1517
1668
  try {
1518
1669
  const parseFeedFrame = (msg) => {
1519
1670
  if (msg.headers?.get("status") === "error") {
1520
- throw createTransportError({
1671
+ const error = createTransportError({
1521
1672
  code: "trellis.feed.failed",
1522
1673
  message: "Trellis stopped the feed.",
1523
1674
  hint: "Retry the subscription. If it keeps failing, check Trellis runtime health.",
1524
1675
  context: { feed, subject, frame: msg.string() },
1525
1676
  });
1677
+ recordRuntimeError(error, {
1678
+ surface: "feed",
1679
+ direction: "client",
1680
+ operation: feed,
1681
+ phase: "remote_error",
1682
+ });
1683
+ throw error;
1526
1684
  }
1527
1685
  const json = safeJson(msg).take();
1528
- 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
+ });
1529
1693
  throw json.error;
1694
+ }
1530
1695
  const parsed = parseRuntimeSchema(eventSchema, json).take();
1531
- 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
+ });
1532
1703
  throw parsed.error;
1704
+ }
1533
1705
  return parsed;
1534
1706
  };
1535
1707
  if (firstEvent)
@@ -1557,13 +1729,20 @@ _Trellis_log = new WeakMap(), _Trellis_tasks = new WeakMap(), _Trellis_hasExplic
1557
1729
  await this.nats.flush();
1558
1730
  }
1559
1731
  catch (cause) {
1560
- throw createTransportError({
1732
+ const error = createTransportError({
1561
1733
  code: "trellis.feed.listen_failed",
1562
1734
  message: "Trellis could not listen for feed requests.",
1563
1735
  hint: "Check the service deployment digest and runtime permissions, then restart the service.",
1564
1736
  cause,
1565
1737
  context: { feed, subject },
1566
1738
  });
1739
+ recordRuntimeError(error, {
1740
+ surface: "feed",
1741
+ direction: "server",
1742
+ operation: feed,
1743
+ phase: "listen",
1744
+ });
1745
+ throw error;
1567
1746
  }
1568
1747
  const task = result_1.AsyncResult.try(async () => {
1569
1748
  for await (const msg of sub) {
@@ -1584,6 +1763,12 @@ _Trellis_log = new WeakMap(), _Trellis_tasks = new WeakMap(), _Trellis_hasExplic
1584
1763
  contractDigest: this.contractDigest,
1585
1764
  traceId: traceIdFromTraceparent(msg.headers?.get("traceparent")),
1586
1765
  });
1766
+ recordRuntimeError(error, {
1767
+ surface: "feed",
1768
+ direction: "server",
1769
+ operation: feed,
1770
+ phase: "handler_throw",
1771
+ });
1587
1772
  __classPrivateFieldGet(this, _Trellis_instances, "m", _Trellis_respondWithError).call(this, msg, error);
1588
1773
  }
1589
1774
  })();
@@ -1592,11 +1777,25 @@ _Trellis_log = new WeakMap(), _Trellis_tasks = new WeakMap(), _Trellis_hasExplic
1592
1777
  __classPrivateFieldGet(this, _Trellis_tasks, "f").add(`feed:${feed}`, task);
1593
1778
  }, _Trellis_processFeedMessage = async function _Trellis_processFeedMessage(feed, descriptor, msg, handler) {
1594
1779
  const json = safeJson(msg).take();
1595
- 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
+ });
1596
1787
  return json;
1788
+ }
1597
1789
  const parsed = parseRuntimeSchema(descriptor.input, json).take();
1598
- 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
+ });
1599
1797
  return parsed;
1798
+ }
1600
1799
  const caller = await __classPrivateFieldGet(this, _Trellis_instances, "m", _Trellis_authenticateFeedRequest).call(this, {
1601
1800
  feed,
1602
1801
  subject: msg.subject,
@@ -1605,12 +1804,26 @@ _Trellis_log = new WeakMap(), _Trellis_tasks = new WeakMap(), _Trellis_hasExplic
1605
1804
  requiredCapabilities: descriptor.subscribeCapabilities,
1606
1805
  });
1607
1806
  const callerValue = caller.take();
1608
- 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
+ });
1609
1814
  return callerValue;
1815
+ }
1610
1816
  if (!msg.reply) {
1611
- return (0, result_1.err)(new index_js_1.UnexpectedError({
1817
+ const error = new index_js_1.UnexpectedError({
1612
1818
  context: { feed, reason: "missing_reply" },
1613
- }));
1819
+ });
1820
+ recordRuntimeError(error, {
1821
+ surface: "feed",
1822
+ direction: "server",
1823
+ operation: feed,
1824
+ phase: "handshake",
1825
+ });
1826
+ return (0, result_1.err)(error);
1614
1827
  }
1615
1828
  const readyHeaders = (0, nats_core_1.headers)();
1616
1829
  readyHeaders.set("feed-status", "ready");
@@ -1624,15 +1837,44 @@ _Trellis_log = new WeakMap(), _Trellis_tasks = new WeakMap(), _Trellis_hasExplic
1624
1837
  signal: controller.signal,
1625
1838
  emit: (event) => result_1.AsyncResult.from((async () => {
1626
1839
  const payload = encodeRuntimeSchema(descriptor.event, event).take();
1627
- 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
+ });
1628
1847
  return payload;
1848
+ }
1629
1849
  if (!msg.reply) {
1630
- return (0, result_1.err)(new index_js_1.UnexpectedError({
1850
+ const error = new index_js_1.UnexpectedError({
1631
1851
  context: { feed, reason: "missing_reply" },
1632
- }));
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);
1633
1877
  }
1634
- this.nats.publish(msg.reply, payload);
1635
- await this.nats.flush();
1636
1878
  return (0, result_1.ok)(undefined);
1637
1879
  })()),
1638
1880
  });
@@ -1640,14 +1882,21 @@ _Trellis_log = new WeakMap(), _Trellis_tasks = new WeakMap(), _Trellis_hasExplic
1640
1882
  ? handlerResult.take()
1641
1883
  : handlerResult;
1642
1884
  if ((0, result_1.isErr)(handlerOutcome)) {
1643
- return (0, result_1.err)(annotateHandlerBoundaryError(handlerOutcome.error, {
1885
+ const error = annotateHandlerBoundaryError(handlerOutcome.error, {
1644
1886
  feed,
1645
1887
  requestId: msg.headers?.get("request-id"),
1646
1888
  service: this.name,
1647
1889
  contractId: this.contractId,
1648
1890
  contractDigest: this.contractDigest,
1649
1891
  traceId: traceIdFromTraceparent(msg.headers?.get("traceparent")),
1650
- }));
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);
1651
1900
  }
1652
1901
  return (0, result_1.ok)(undefined);
1653
1902
  }
@@ -1699,31 +1948,43 @@ _Trellis_log = new WeakMap(), _Trellis_tasks = new WeakMap(), _Trellis_hasExplic
1699
1948
  }, _Trellis_processRPCMessage = async function _Trellis_processRPCMessage(method, ctx, msg, fn, handlerTrellis) {
1700
1949
  __classPrivateFieldGet(this, _Trellis_log, "f").debug({ method: String(method), subject: msg.subject }, "Processing RPC message");
1701
1950
  // Extract trace context from incoming NATS headers
1702
- 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)({
1703
1952
  get: (k) => msg.headers?.get(k) ?? undefined,
1704
1953
  set: () => { }, // Server doesn't need to set headers on incoming messages
1705
1954
  }));
1706
1955
  // Start a server span for this RPC handler
1707
- const span = (0, tracing_js_1.startServerSpan)(method, msg.subject, parentContext);
1956
+ const span = (0, mod_js_2.startServerSpan)(method, msg.subject, parentContext);
1708
1957
  const incomingTraceId = traceIdFromTraceparent(msg.headers?.get("traceparent"));
1709
1958
  // Execute the handler within the span's context
1710
- return (0, tracing_js_1.withSpanAsync)(span, async () => {
1959
+ return (0, mod_js_2.withSpanAsync)(span, async () => {
1711
1960
  const execute = async () => {
1712
1961
  const jsonData = safeJson(msg).take();
1713
1962
  if ((0, result_1.isErr)(jsonData)) {
1714
1963
  __classPrivateFieldGet(this, _Trellis_log, "f").warn({ method, error: jsonData.error.message }, "Failed to parse JSON");
1715
1964
  span.setStatus({
1716
- code: tracing_js_1.SpanStatusCode.ERROR,
1965
+ code: mod_js_2.SpanStatusCode.ERROR,
1717
1966
  message: "Failed to parse JSON",
1718
1967
  });
1968
+ recordRuntimeError(jsonData.error, {
1969
+ surface: "rpc",
1970
+ direction: "server",
1971
+ operation: String(method),
1972
+ phase: "parse",
1973
+ });
1719
1974
  return jsonData;
1720
1975
  }
1721
1976
  const parsedInput = parseRuntimeSchema(ctx.input, jsonData).take();
1722
1977
  if ((0, result_1.isErr)(parsedInput)) {
1723
1978
  span.setStatus({
1724
- code: tracing_js_1.SpanStatusCode.ERROR,
1979
+ code: mod_js_2.SpanStatusCode.ERROR,
1725
1980
  message: "Input validation failed",
1726
1981
  });
1982
+ recordRuntimeError(parsedInput.error, {
1983
+ surface: "rpc",
1984
+ direction: "server",
1985
+ operation: String(method),
1986
+ phase: "input_validation",
1987
+ });
1727
1988
  return parsedInput;
1728
1989
  }
1729
1990
  let caller;
@@ -1746,22 +2007,43 @@ _Trellis_log = new WeakMap(), _Trellis_tasks = new WeakMap(), _Trellis_hasExplic
1746
2007
  if (!sessionKey) {
1747
2008
  __classPrivateFieldGet(this, _Trellis_log, "f").warn({ method }, "Missing session-key header");
1748
2009
  span.setStatus({
1749
- code: tracing_js_1.SpanStatusCode.ERROR,
2010
+ code: mod_js_2.SpanStatusCode.ERROR,
1750
2011
  message: "Missing session-key",
1751
2012
  });
1752
- 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);
1753
2021
  }
1754
2022
  if (!proof) {
1755
2023
  __classPrivateFieldGet(this, _Trellis_log, "f").warn({ method }, "Missing proof in request");
1756
2024
  span.setStatus({
1757
- code: tracing_js_1.SpanStatusCode.ERROR,
2025
+ code: mod_js_2.SpanStatusCode.ERROR,
1758
2026
  message: "Missing proof",
1759
2027
  });
1760
- 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);
1761
2036
  }
1762
2037
  const iat = Number(iatHeader);
1763
2038
  if (!Number.isSafeInteger(iat) || !requestId) {
1764
- 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);
1765
2047
  }
1766
2048
  // Verify proof signature locally using the raw request bytes we received.
1767
2049
  const payloadBytes = msg.data ?? new Uint8Array();
@@ -1777,13 +2059,20 @@ _Trellis_log = new WeakMap(), _Trellis_tasks = new WeakMap(), _Trellis_hasExplic
1777
2059
  verifyResult.take() === true;
1778
2060
  if (!signatureOk) {
1779
2061
  span.setStatus({
1780
- code: tracing_js_1.SpanStatusCode.ERROR,
2062
+ code: mod_js_2.SpanStatusCode.ERROR,
1781
2063
  message: "Invalid signature",
1782
2064
  });
1783
- return (0, result_1.err)(new index_js_1.AuthError({
2065
+ const error = new index_js_1.AuthError({
1784
2066
  reason: "invalid_signature",
1785
2067
  context: { sessionKey },
1786
- }));
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);
1787
2076
  }
1788
2077
  let auth;
1789
2078
  for (let attempt = 0; attempt < DEFAULT_AUTH_VALIDATE_SESSION_RETRY_ATTEMPTS; attempt++) {
@@ -1809,9 +2098,16 @@ _Trellis_log = new WeakMap(), _Trellis_tasks = new WeakMap(), _Trellis_hasExplic
1809
2098
  await sleep(DEFAULT_AUTH_VALIDATE_SESSION_RETRY_MS * (attempt + 1));
1810
2099
  }
1811
2100
  if (!auth) {
1812
- return (0, result_1.err)(new index_js_1.UnexpectedError({
2101
+ const error = new index_js_1.UnexpectedError({
1813
2102
  context: { reason: "missing_auth_validate_result" },
1814
- }));
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);
1815
2111
  }
1816
2112
  if (auth instanceof Error) {
1817
2113
  __classPrivateFieldGet(this, _Trellis_log, "f").warn({
@@ -1823,37 +2119,64 @@ _Trellis_log = new WeakMap(), _Trellis_tasks = new WeakMap(), _Trellis_hasExplic
1823
2119
  : undefined,
1824
2120
  }, "Auth.Requests.Validate failed");
1825
2121
  span.setStatus({
1826
- code: tracing_js_1.SpanStatusCode.ERROR,
2122
+ code: mod_js_2.SpanStatusCode.ERROR,
1827
2123
  message: "Auth.Requests.Validate failed",
1828
2124
  });
1829
2125
  if (auth instanceof result_1.BaseError) {
2126
+ recordRuntimeError(auth, {
2127
+ surface: "rpc",
2128
+ direction: "server",
2129
+ operation: String(method),
2130
+ phase: "auth",
2131
+ });
1830
2132
  return (0, result_1.err)(auth);
1831
2133
  }
1832
- 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);
1833
2142
  }
1834
2143
  if (!auth.allowed) {
1835
2144
  span.setStatus({
1836
- code: tracing_js_1.SpanStatusCode.ERROR,
2145
+ code: mod_js_2.SpanStatusCode.ERROR,
1837
2146
  message: "Insufficient permissions",
1838
2147
  });
1839
- return (0, result_1.err)(new index_js_1.AuthError({
2148
+ const error = new index_js_1.AuthError({
1840
2149
  reason: "insufficient_permissions",
1841
2150
  context: {
1842
2151
  requiredCapabilities: ctx.callerCapabilities,
1843
2152
  userCapabilities: auth.caller.capabilities,
1844
2153
  },
1845
- }));
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);
1846
2162
  }
1847
2163
  if (typeof msg.reply !== "string" ||
1848
2164
  !msg.reply.startsWith(`${auth.inboxPrefix}.`)) {
1849
2165
  span.setStatus({
1850
- code: tracing_js_1.SpanStatusCode.ERROR,
2166
+ code: mod_js_2.SpanStatusCode.ERROR,
1851
2167
  message: "Reply subject mismatch",
1852
2168
  });
1853
- return (0, result_1.err)(new index_js_1.AuthError({
2169
+ const error = new index_js_1.AuthError({
1854
2170
  reason: "reply_subject_mismatch",
1855
2171
  context: { expected: auth.inboxPrefix, actual: msg.reply },
1856
- }));
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);
1857
2180
  }
1858
2181
  caller = auth.caller;
1859
2182
  }
@@ -1897,10 +2220,16 @@ _Trellis_log = new WeakMap(), _Trellis_tasks = new WeakMap(), _Trellis_hasExplic
1897
2220
  : error.cause,
1898
2221
  }, "Handler threw unexpectedly.");
1899
2222
  span.setStatus({
1900
- code: tracing_js_1.SpanStatusCode.ERROR,
2223
+ code: mod_js_2.SpanStatusCode.ERROR,
1901
2224
  message: error.message,
1902
2225
  });
1903
2226
  span.recordException(error);
2227
+ recordRuntimeError(error, {
2228
+ surface: "rpc",
2229
+ direction: "server",
2230
+ operation: String(method),
2231
+ phase: "handler_throw",
2232
+ });
1904
2233
  return (0, result_1.err)(error);
1905
2234
  }
1906
2235
  const handlerResult = handlerResultWrapped.take();
@@ -1923,20 +2252,32 @@ _Trellis_log = new WeakMap(), _Trellis_tasks = new WeakMap(), _Trellis_hasExplic
1923
2252
  : error.cause,
1924
2253
  }, "Handler returned error.");
1925
2254
  span.setStatus({
1926
- code: tracing_js_1.SpanStatusCode.ERROR,
2255
+ code: mod_js_2.SpanStatusCode.ERROR,
1927
2256
  message: error.message,
1928
2257
  });
2258
+ recordRuntimeError(error, {
2259
+ surface: "rpc",
2260
+ direction: "server",
2261
+ operation: String(method),
2262
+ phase: "handler_result",
2263
+ });
1929
2264
  return (0, result_1.err)(error);
1930
2265
  }
1931
2266
  const encoded = (0, codec_js_1.encodeSchema)(ctx.output, handlerOutcome).take();
1932
2267
  if ((0, result_1.isErr)(encoded)) {
1933
2268
  span.setStatus({
1934
- code: tracing_js_1.SpanStatusCode.ERROR,
2269
+ code: mod_js_2.SpanStatusCode.ERROR,
1935
2270
  message: "Output encoding failed",
1936
2271
  });
2272
+ recordRuntimeError(encoded.error, {
2273
+ surface: "rpc",
2274
+ direction: "server",
2275
+ operation: String(method),
2276
+ phase: "output_encoding",
2277
+ });
1937
2278
  return encoded;
1938
2279
  }
1939
- span.setStatus({ code: tracing_js_1.SpanStatusCode.OK });
2280
+ span.setStatus({ code: mod_js_2.SpanStatusCode.OK });
1940
2281
  return (0, result_1.ok)(encoded);
1941
2282
  };
1942
2283
  const result = await execute();
@@ -2010,6 +2351,12 @@ _Trellis_log = new WeakMap(), _Trellis_tasks = new WeakMap(), _Trellis_hasExplic
2010
2351
  const m = parsedEvent.take();
2011
2352
  if ((0, result_1.isErr)(m)) {
2012
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
+ });
2013
2360
  continue;
2014
2361
  }
2015
2362
  const handlerResult = await __classPrivateFieldGet(this, _Trellis_instances, "m", _Trellis_invokeEventHandler).call(this, {
@@ -2021,6 +2368,12 @@ _Trellis_log = new WeakMap(), _Trellis_tasks = new WeakMap(), _Trellis_hasExplic
2021
2368
  });
2022
2369
  const handlerValue = handlerResult.take();
2023
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
+ });
2024
2377
  __classPrivateFieldGet(this, _Trellis_log, "f").error({
2025
2378
  error: handlerValue.error.toSerializable(),
2026
2379
  event,
@@ -2220,6 +2573,12 @@ _Trellis_log = new WeakMap(), _Trellis_tasks = new WeakMap(), _Trellis_hasExplic
2220
2573
  const eventPayload = parsedEvent.take();
2221
2574
  if ((0, result_1.isErr)(eventPayload)) {
2222
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
+ });
2223
2582
  msg.term();
2224
2583
  failed = true;
2225
2584
  break;
@@ -2234,6 +2593,12 @@ _Trellis_log = new WeakMap(), _Trellis_tasks = new WeakMap(), _Trellis_hasExplic
2234
2593
  });
2235
2594
  const handlerValue = handlerResult.take();
2236
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
+ });
2237
2602
  __classPrivateFieldGet(this, _Trellis_log, "f").error({
2238
2603
  error: handlerValue.error.toSerializable(),
2239
2604
  event: registration.event,
@@ -2309,8 +2674,8 @@ _Trellis_log = new WeakMap(), _Trellis_tasks = new WeakMap(), _Trellis_hasExplic
2309
2674
  }));
2310
2675
  }, _Trellis_requestJson = function _Trellis_requestJson(subject, body) {
2311
2676
  return result_1.AsyncResult.from((async () => {
2312
- const span = (0, tracing_js_1.startClientSpan)(subject, subject);
2313
- 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 () => {
2314
2679
  try {
2315
2680
  const payload = JSON.stringify(body);
2316
2681
  const authHeaders = await __classPrivateFieldGet(this, _Trellis_instances, "m", _Trellis_createProof).call(this, subject, payload);
@@ -2319,7 +2684,7 @@ _Trellis_log = new WeakMap(), _Trellis_tasks = new WeakMap(), _Trellis_hasExplic
2319
2684
  headers.set("proof", authHeaders.proof);
2320
2685
  headers.set("iat", String(authHeaders.iat));
2321
2686
  headers.set("request-id", authHeaders.requestId);
2322
- (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);
2323
2688
  const response = (await __classPrivateFieldGet(this, _Trellis_instances, "m", _Trellis_requestMessageWithRetry).call(this, {
2324
2689
  subject,
2325
2690
  payload,
@@ -2328,9 +2693,15 @@ _Trellis_log = new WeakMap(), _Trellis_tasks = new WeakMap(), _Trellis_hasExplic
2328
2693
  })).take();
2329
2694
  if ((0, result_1.isErr)(response)) {
2330
2695
  span.setStatus({
2331
- code: tracing_js_1.SpanStatusCode.ERROR,
2696
+ code: mod_js_2.SpanStatusCode.ERROR,
2332
2697
  message: response.error.message,
2333
2698
  });
2699
+ recordRuntimeError(response.error, {
2700
+ surface: "operation",
2701
+ direction: "client",
2702
+ operation: "requestJson",
2703
+ phase: "request_send",
2704
+ });
2334
2705
  return response;
2335
2706
  }
2336
2707
  const json = safeJson(response).take();
@@ -2343,21 +2714,33 @@ _Trellis_log = new WeakMap(), _Trellis_tasks = new WeakMap(), _Trellis_hasExplic
2343
2714
  context: { subject },
2344
2715
  });
2345
2716
  span.setStatus({
2346
- code: tracing_js_1.SpanStatusCode.ERROR,
2717
+ code: mod_js_2.SpanStatusCode.ERROR,
2347
2718
  message: error.message,
2348
2719
  });
2720
+ recordRuntimeError(error, {
2721
+ surface: "operation",
2722
+ direction: "client",
2723
+ operation: "requestJson",
2724
+ phase: "response_decoding",
2725
+ });
2349
2726
  return (0, result_1.err)(error);
2350
2727
  }
2351
- span.setStatus({ code: tracing_js_1.SpanStatusCode.OK });
2728
+ span.setStatus({ code: mod_js_2.SpanStatusCode.OK });
2352
2729
  return (0, result_1.ok)(json);
2353
2730
  }
2354
2731
  catch (cause) {
2355
2732
  const error = new index_js_1.UnexpectedError({ cause });
2356
2733
  span.setStatus({
2357
- code: tracing_js_1.SpanStatusCode.ERROR,
2734
+ code: mod_js_2.SpanStatusCode.ERROR,
2358
2735
  message: error.message,
2359
2736
  });
2360
2737
  span.recordException(error);
2738
+ recordRuntimeError(error, {
2739
+ surface: "operation",
2740
+ direction: "client",
2741
+ operation: "requestJson",
2742
+ phase: "unexpected",
2743
+ });
2361
2744
  return (0, result_1.err)(error);
2362
2745
  }
2363
2746
  finally {
@@ -2385,35 +2768,56 @@ _Trellis_log = new WeakMap(), _Trellis_tasks = new WeakMap(), _Trellis_hasExplic
2385
2768
  }
2386
2769
  catch (cause) {
2387
2770
  sub.unsubscribe();
2388
- return (0, result_1.err)(createTransportError({
2771
+ const error = createTransportError({
2389
2772
  code: "trellis.watch.failed",
2390
2773
  message: "Trellis could not start the operation watch.",
2391
2774
  hint: "Retry watching the operation. If it keeps failing, reconnect to Trellis and try again.",
2392
2775
  cause,
2393
2776
  context: { subject },
2394
- }));
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);
2395
2785
  }
2396
2786
  return (0, result_1.ok)((async function* () {
2397
2787
  try {
2398
2788
  for await (const msg of sub) {
2399
2789
  if (msg.headers?.get("status") === "error") {
2400
- yield (0, result_1.err)(createTransportError({
2790
+ const error = createTransportError({
2401
2791
  code: "trellis.watch.failed",
2402
2792
  message: "Trellis stopped the operation watch.",
2403
2793
  hint: "Retry watching the operation. If it keeps happening, reconnect to Trellis and try again.",
2404
2794
  context: { subject, frame: msg.string() },
2405
- }));
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);
2406
2803
  continue;
2407
2804
  }
2408
2805
  const json = safeJson(msg).take();
2409
2806
  if ((0, result_1.isErr)(json)) {
2410
- yield (0, result_1.err)(createTransportError({
2807
+ const error = createTransportError({
2411
2808
  code: "trellis.watch.invalid_response",
2412
2809
  message: "Trellis returned an invalid watch update.",
2413
2810
  hint: "Retry watching the operation. If it keeps happening, reconnect to Trellis and try again.",
2414
2811
  cause: json.error.cause,
2415
2812
  context: { subject },
2416
- }));
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);
2417
2821
  continue;
2418
2822
  }
2419
2823
  yield (0, result_1.ok)(json);