@spfn/monitor 0.1.0-beta.15 → 0.1.0-beta.17

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -1,8 +1,8 @@
1
1
  import * as _spfn_core_nextjs from '@spfn/core/nextjs';
2
2
  import * as _spfn_core_route from '@spfn/core/route';
3
3
  import * as _sinclair_typebox from '@sinclair/typebox';
4
- import { M as MonitorStats, m as monitorRouter } from './index-C9IUDNIv.js';
5
- export { a as ERROR_GROUP_STATUSES, E as ErrorGroupStatus, b as LOG_LEVELS, L as LogLevel } from './index-C9IUDNIv.js';
4
+ import { M as MonitorStats, m as monitorRouter } from './index-BiN0PoSx.js';
5
+ export { a as ERROR_GROUP_STATUSES, E as ErrorGroupStatus, b as LOG_LEVELS, L as LogLevel } from './index-BiN0PoSx.js';
6
6
  import 'drizzle-orm/pg-core';
7
7
 
8
8
  /**
@@ -33,14 +33,14 @@ declare const monitorApi: _spfn_core_nextjs.Client<_spfn_core_route.Router<{
33
33
  offset: _sinclair_typebox.TOptional<_sinclair_typebox.TNumber>;
34
34
  }>;
35
35
  }, {}, {
36
- status: "active" | "resolved" | "ignored";
37
- path: string;
38
36
  id: number;
39
37
  fingerprint: string;
40
38
  name: string;
41
39
  message: string;
40
+ path: string;
42
41
  method: string;
43
42
  statusCode: number;
43
+ status: "active" | "resolved" | "ignored";
44
44
  count: number;
45
45
  firstSeenAt: Date;
46
46
  lastSeenAt: Date;
@@ -54,14 +54,14 @@ declare const monitorApi: _spfn_core_nextjs.Client<_spfn_core_route.Router<{
54
54
  }>;
55
55
  }, {}, {
56
56
  group: {
57
- status: "active" | "resolved" | "ignored";
58
- path: string;
59
57
  id: number;
60
58
  fingerprint: string;
61
59
  name: string;
62
60
  message: string;
61
+ path: string;
63
62
  method: string;
64
63
  statusCode: number;
64
+ status: "active" | "resolved" | "ignored";
65
65
  count: number;
66
66
  firstSeenAt: Date;
67
67
  lastSeenAt: Date;
@@ -70,15 +70,15 @@ declare const monitorApi: _spfn_core_nextjs.Client<_spfn_core_route.Router<{
70
70
  updatedAt: Date;
71
71
  };
72
72
  events: {
73
- query: Record<string, string> | null;
74
73
  id: number;
75
74
  statusCode: number;
76
75
  createdAt: Date;
77
76
  updatedAt: Date;
78
- headers: Record<string, string> | null;
77
+ query: Record<string, string> | null;
79
78
  groupId: number;
80
79
  requestId: string | null;
81
80
  userId: string | null;
81
+ headers: Record<string, string> | null;
82
82
  stackTrace: string | null;
83
83
  metadata: Record<string, unknown> | null;
84
84
  }[];
@@ -91,14 +91,14 @@ declare const monitorApi: _spfn_core_nextjs.Client<_spfn_core_route.Router<{
91
91
  status: _sinclair_typebox.TString;
92
92
  }>;
93
93
  }, {}, {
94
- status: "active" | "resolved" | "ignored";
95
- path: string;
96
94
  id: number;
97
95
  fingerprint: string;
98
96
  name: string;
99
97
  message: string;
98
+ path: string;
100
99
  method: string;
101
100
  statusCode: number;
101
+ status: "active" | "resolved" | "ignored";
102
102
  count: number;
103
103
  firstSeenAt: Date;
104
104
  lastSeenAt: Date;
@@ -115,15 +115,15 @@ declare const monitorApi: _spfn_core_nextjs.Client<_spfn_core_route.Router<{
115
115
  offset: _sinclair_typebox.TOptional<_sinclair_typebox.TNumber>;
116
116
  }>;
117
117
  }, {}, {
118
- query: Record<string, string> | null;
119
118
  id: number;
120
119
  statusCode: number;
121
120
  createdAt: Date;
122
121
  updatedAt: Date;
123
- headers: Record<string, string> | null;
122
+ query: Record<string, string> | null;
124
123
  groupId: number;
125
124
  requestId: string | null;
126
125
  userId: string | null;
126
+ headers: Record<string, string> | null;
127
127
  stackTrace: string | null;
128
128
  metadata: Record<string, unknown> | null;
129
129
  }[]>;
package/dist/server.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { E as ErrorGroupStatus, c as ErrorGroup, N as NewErrorGroup, L as LogLevel, d as NewLog, e as Log } from './index-C9IUDNIv.js';
2
- export { a as ERROR_GROUP_STATUSES, b as LOG_LEVELS, M as MonitorStats, f as errorGroups, g as getMonitorStats, l as logs, m as monitorRouter } from './index-C9IUDNIv.js';
1
+ import { E as ErrorGroupStatus, c as ErrorGroup, N as NewErrorGroup, L as LogLevel, d as NewLog, e as Log } from './index-BiN0PoSx.js';
2
+ export { a as ERROR_GROUP_STATUSES, b as LOG_LEVELS, M as MonitorStats, f as errorGroups, g as getMonitorStats, l as logs, m as monitorRouter } from './index-BiN0PoSx.js';
3
3
  import { BaseRepository } from '@spfn/core/db';
4
4
  import * as drizzle_orm_pg_core from 'drizzle-orm/pg-core';
5
5
  import * as _spfn_core_logger from '@spfn/core/logger';
package/dist/server.js CHANGED
@@ -963,14 +963,14 @@ function Number2(options) {
963
963
  }
964
964
 
965
965
  // ../../node_modules/.pnpm/@sinclair+typebox@0.34.41/node_modules/@sinclair/typebox/build/esm/type/string/string.mjs
966
- function String(options) {
966
+ function String2(options) {
967
967
  return CreateType({ [Kind]: "String", type: "string" }, options);
968
968
  }
969
969
 
970
970
  // ../../node_modules/.pnpm/@sinclair+typebox@0.34.41/node_modules/@sinclair/typebox/build/esm/type/template-literal/syntax.mjs
971
971
  function* FromUnion(syntax) {
972
972
  const trim = syntax.trim().replace(/"|'/g, "");
973
- return trim === "boolean" ? yield Boolean() : trim === "number" ? yield Number2() : trim === "bigint" ? yield BigInt() : trim === "string" ? yield String() : yield (() => {
973
+ return trim === "boolean" ? yield Boolean() : trim === "number" ? yield Number2() : trim === "bigint" ? yield BigInt() : trim === "string" ? yield String2() : yield (() => {
974
974
  const literals = trim.split("|").map((literal) => Literal(literal.trim()));
975
975
  return literals.length === 0 ? Never() : literals.length === 1 ? literals[0] : UnionEvaluated(literals);
976
976
  })();
@@ -1687,7 +1687,7 @@ function FromPromise2(left, right) {
1687
1687
  return IsStructuralRight(right) ? StructuralRight(left, right) : type_exports.IsObject(right) && IsObjectPromiseLike(right) ? ExtendsResult.True : !type_exports.IsPromise(right) ? ExtendsResult.False : IntoBooleanResult(Visit3(left.item, right.item));
1688
1688
  }
1689
1689
  function RecordKey(schema) {
1690
- return PatternNumberExact in schema.patternProperties ? Number2() : PatternStringExact in schema.patternProperties ? String() : Throw("Unknown record key pattern");
1690
+ return PatternNumberExact in schema.patternProperties ? Number2() : PatternStringExact in schema.patternProperties ? String2() : Throw("Unknown record key pattern");
1691
1691
  }
1692
1692
  function RecordValue(schema) {
1693
1693
  return PatternNumberExact in schema.patternProperties ? schema.patternProperties[PatternNumberExact] : PatternStringExact in schema.patternProperties ? schema.patternProperties[PatternStringExact] : Throw("Unable to get record value schema");
@@ -1707,8 +1707,8 @@ function FromRecord(left, right) {
1707
1707
  return IsStructuralRight(right) ? StructuralRight(left, right) : type_exports.IsObject(right) ? FromObjectRight(left, right) : !type_exports.IsRecord(right) ? ExtendsResult.False : Visit3(RecordValue(left), RecordValue(right));
1708
1708
  }
1709
1709
  function FromRegExp(left, right) {
1710
- const L = type_exports.IsRegExp(left) ? String() : left;
1711
- const R = type_exports.IsRegExp(right) ? String() : right;
1710
+ const L = type_exports.IsRegExp(left) ? String2() : left;
1711
+ const R = type_exports.IsRegExp(right) ? String2() : right;
1712
1712
  return Visit3(L, R);
1713
1713
  }
1714
1714
  function FromStringRight(left, right) {
@@ -1937,7 +1937,7 @@ function RecordPattern(record) {
1937
1937
  }
1938
1938
  function RecordKey2(type) {
1939
1939
  const pattern = RecordPattern(type);
1940
- return pattern === PatternStringExact ? String() : pattern === PatternNumberExact ? Number2() : String({ pattern });
1940
+ return pattern === PatternStringExact ? String2() : pattern === PatternNumberExact ? Number2() : String2({ pattern });
1941
1941
  }
1942
1942
  function RecordValue2(type) {
1943
1943
  return type.patternProperties[RecordPattern(type)];
@@ -2606,7 +2606,7 @@ __export(type_exports2, {
2606
2606
  Required: () => Required,
2607
2607
  Rest: () => Rest,
2608
2608
  ReturnType: () => ReturnType,
2609
- String: () => String,
2609
+ String: () => String2,
2610
2610
  Symbol: () => Symbol2,
2611
2611
  TemplateLiteral: () => TemplateLiteral,
2612
2612
  Transform: () => Transform,
@@ -3045,26 +3045,30 @@ async function trackError(err, ctx, metadata) {
3045
3045
  firstSeenAt: now,
3046
3046
  lastSeenAt: now
3047
3047
  });
3048
- const event = await createEvent(group.id, err, ctx, metadata);
3048
+ const event = await safeCreateEvent(group.id, err, ctx, metadata);
3049
3049
  logger2.info("New error group tracked", { fingerprint, groupId: group.id });
3050
- notifyErrorToSlack(group, event, "new", ctx.environment).catch((e) => logger2.warn("Slack notification failed", e));
3050
+ if (event) {
3051
+ notifyErrorToSlack(group, event, "new", ctx.environment).catch((e) => logger2.warn("Slack notification failed", e));
3052
+ }
3051
3053
  return;
3052
3054
  }
3053
3055
  if (existing.status === "resolved") {
3054
3056
  await errorGroupsRepository.updateStatus(existing.id, "active");
3055
3057
  await errorGroupsRepository.incrementCount(existing.id);
3056
- const event = await createEvent(existing.id, err, ctx, metadata);
3058
+ const event = await safeCreateEvent(existing.id, err, ctx, metadata);
3057
3059
  logger2.info("Error group reopened", { fingerprint, groupId: existing.id });
3058
- notifyErrorToSlack(
3059
- { ...existing, status: "active", count: existing.count + 1 },
3060
- event,
3061
- "reopened",
3062
- ctx.environment
3063
- ).catch((e) => logger2.warn("Slack notification failed", e));
3060
+ if (event) {
3061
+ notifyErrorToSlack(
3062
+ { ...existing, status: "active", count: existing.count + 1 },
3063
+ event,
3064
+ "reopened",
3065
+ ctx.environment
3066
+ ).catch((e) => logger2.warn("Slack notification failed", e));
3067
+ }
3064
3068
  return;
3065
3069
  }
3066
3070
  await errorGroupsRepository.incrementCount(existing.id);
3067
- await createEvent(existing.id, err, ctx, metadata);
3071
+ await safeCreateEvent(existing.id, err, ctx, metadata);
3068
3072
  }
3069
3073
  async function updateErrorGroupStatus(groupId, newStatus) {
3070
3074
  const group = await errorGroupsRepository.findById(groupId);
@@ -3082,17 +3086,23 @@ async function updateErrorGroupStatus(groupId, newStatus) {
3082
3086
  });
3083
3087
  return updated;
3084
3088
  }
3085
- async function createEvent(groupId, err, ctx, metadata) {
3086
- return await errorEventsRepository.create({
3087
- groupId,
3088
- requestId: ctx.requestId,
3089
- userId: ctx.userId,
3090
- statusCode: ctx.statusCode,
3091
- headers: ctx.headers,
3092
- query: ctx.query,
3093
- stackTrace: err.stack,
3094
- metadata
3095
- });
3089
+ async function safeCreateEvent(groupId, err, ctx, metadata) {
3090
+ try {
3091
+ return await errorEventsRepository.create({
3092
+ groupId,
3093
+ requestId: ctx.requestId,
3094
+ userId: ctx.userId,
3095
+ statusCode: ctx.statusCode,
3096
+ headers: ctx.headers,
3097
+ query: ctx.query,
3098
+ stackTrace: err.stack,
3099
+ metadata
3100
+ });
3101
+ } catch (e) {
3102
+ const cause = e instanceof Error && e.cause instanceof Error ? e.cause : e;
3103
+ logger2.warn("Failed to create error event", cause, { groupId });
3104
+ return null;
3105
+ }
3096
3106
  }
3097
3107
 
3098
3108
  // src/server/services/log.service.ts
@@ -3292,7 +3302,7 @@ function createMonitorErrorHandler(options = {}) {
3292
3302
  path: ctx.path,
3293
3303
  method: ctx.method,
3294
3304
  requestId: ctx.requestId,
3295
- userId: ctx.userId,
3305
+ userId: ctx.userId != null ? String(ctx.userId) : void 0,
3296
3306
  headers: ctx.request.headers,
3297
3307
  query: ctx.request.query,
3298
3308
  environment: options.environment