@statly/observe 1.1.0 → 1.2.1
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/README.md +104 -0
- package/dist/{chunk-HYFH22G6.mjs → chunk-RLSLJL6N.js} +77 -78
- package/dist/chunk-RUEXBTHM.js +1422 -0
- package/dist/{cli.mjs → cli.cjs} +26 -3
- package/dist/cli.js +3 -26
- package/dist/index.cjs +2837 -0
- package/dist/{index.d.mts → index.d.cts} +4 -3
- package/dist/index.d.ts +1 -0
- package/dist/index.js +81 -1352
- package/dist/integrations/express.cjs +1108 -0
- package/dist/integrations/express.js +8 -1078
- package/dist/integrations/fastify.cjs +1117 -0
- package/dist/integrations/fastify.js +9 -1086
- package/dist/integrations/nextjs.cjs +1167 -0
- package/dist/integrations/nextjs.js +12 -1133
- package/dist/logger/index.cjs +1483 -0
- package/dist/logger/index.d.cts +671 -0
- package/dist/logger/index.d.ts +671 -0
- package/dist/logger/index.js +56 -0
- package/dist/{telemetry-CXHOTW3Y.mjs → telemetry-JOMOMZ25.js} +1 -1
- package/package.json +9 -3
- package/dist/index.mjs +0 -57
- package/dist/integrations/express.mjs +0 -9
- package/dist/integrations/fastify.mjs +0 -11
- package/dist/integrations/nextjs.mjs +0 -17
- /package/dist/{chunk-J5AHUFP2.mjs → chunk-NKQPBSKX.js} +0 -0
- /package/dist/{cli.d.mts → cli.d.cts} +0 -0
- /package/dist/integrations/{express.d.mts → express.d.cts} +0 -0
- /package/dist/integrations/{fastify.d.mts → fastify.d.cts} +0 -0
- /package/dist/integrations/{nextjs.d.mts → nextjs.d.cts} +0 -0
package/README.md
CHANGED
|
@@ -12,6 +12,7 @@ Error tracking and monitoring for JavaScript and TypeScript applications. Captur
|
|
|
12
12
|
## Features
|
|
13
13
|
|
|
14
14
|
- Automatic error capturing with stack traces
|
|
15
|
+
- **Structured Logging**: Production-grade logging with automatic scrubbing
|
|
15
16
|
- **Distributed Tracing**: Visualize function execution and call hierarchies
|
|
16
17
|
- **Performance Metrics**: Automated capture of latency and success rates
|
|
17
18
|
- Breadcrumbs for debugging context
|
|
@@ -127,6 +128,109 @@ try {
|
|
|
127
128
|
}
|
|
128
129
|
```
|
|
129
130
|
|
|
131
|
+
## Structured Logging
|
|
132
|
+
|
|
133
|
+
The Logger class provides production-grade structured logging with automatic secret scrubbing, session management, and batching.
|
|
134
|
+
|
|
135
|
+
### Quick Start
|
|
136
|
+
|
|
137
|
+
```typescript
|
|
138
|
+
import { Logger } from '@statly/observe';
|
|
139
|
+
|
|
140
|
+
const logger = Logger.create({
|
|
141
|
+
dsn: 'https://sk_live_xxx@statly.live/your-org',
|
|
142
|
+
environment: 'production',
|
|
143
|
+
loggerName: 'api-server',
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
// Log at different levels
|
|
147
|
+
logger.trace('Entering function', { args: [1, 2, 3] });
|
|
148
|
+
logger.debug('Processing request', { requestId: 'req_123' });
|
|
149
|
+
logger.info('User logged in', { userId: 'user_123' });
|
|
150
|
+
logger.warn('Rate limit approaching', { current: 95, limit: 100 });
|
|
151
|
+
logger.error('Payment failed', { orderId: 'ord_456', error: 'Card declined' });
|
|
152
|
+
logger.fatal('Database connection lost', { host: 'db.example.com' });
|
|
153
|
+
logger.audit('User role changed', { userId: 'user_123', newRole: 'admin' });
|
|
154
|
+
|
|
155
|
+
// Always close before exit
|
|
156
|
+
await logger.close();
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
### Child Loggers
|
|
160
|
+
|
|
161
|
+
Create child loggers with inherited context:
|
|
162
|
+
|
|
163
|
+
```typescript
|
|
164
|
+
const requestLogger = logger.child({
|
|
165
|
+
context: { requestId: 'req_123' },
|
|
166
|
+
loggerName: 'request-handler',
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
requestLogger.info('Processing request'); // Includes requestId automatically
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
### User Context
|
|
173
|
+
|
|
174
|
+
Associate logs with users:
|
|
175
|
+
|
|
176
|
+
```typescript
|
|
177
|
+
logger.setUser({
|
|
178
|
+
id: 'user_123',
|
|
179
|
+
email: 'jane@example.com',
|
|
180
|
+
name: 'Jane Doe',
|
|
181
|
+
});
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
### Secret Scrubbing
|
|
185
|
+
|
|
186
|
+
The logger automatically scrubs sensitive data (API keys, passwords, credit cards, etc.). Add custom patterns:
|
|
187
|
+
|
|
188
|
+
```typescript
|
|
189
|
+
const logger = Logger.create({
|
|
190
|
+
dsn: '...',
|
|
191
|
+
scrubPatterns: [
|
|
192
|
+
/my-custom-secret-[a-z0-9]+/gi,
|
|
193
|
+
/internal-token-\d+/g,
|
|
194
|
+
],
|
|
195
|
+
});
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
### Sample Rates
|
|
199
|
+
|
|
200
|
+
Control log volume with per-level sampling:
|
|
201
|
+
|
|
202
|
+
```typescript
|
|
203
|
+
const logger = Logger.create({
|
|
204
|
+
dsn: '...',
|
|
205
|
+
sampleRates: {
|
|
206
|
+
trace: 0.01, // 1% of trace logs
|
|
207
|
+
debug: 0.1, // 10% of debug logs
|
|
208
|
+
info: 0.5, // 50% of info logs
|
|
209
|
+
warn: 1.0, // 100% of warnings
|
|
210
|
+
error: 1.0, // 100% of errors
|
|
211
|
+
fatal: 1.0, // 100% of fatal
|
|
212
|
+
},
|
|
213
|
+
});
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
### Logger Options
|
|
217
|
+
|
|
218
|
+
| Option | Type | Default | Description |
|
|
219
|
+
|--------|------|---------|-------------|
|
|
220
|
+
| `dsn` | `string` | required | Your project's Data Source Name |
|
|
221
|
+
| `environment` | `string` | `undefined` | Environment name |
|
|
222
|
+
| `release` | `string` | `undefined` | Release/version identifier |
|
|
223
|
+
| `loggerName` | `string` | `undefined` | Logger name for filtering |
|
|
224
|
+
| `sessionId` | `string` | auto-generated | Session ID for grouping logs |
|
|
225
|
+
| `user` | `object` | `undefined` | User context |
|
|
226
|
+
| `defaultContext` | `object` | `{}` | Default context for all logs |
|
|
227
|
+
| `minLevel` | `LogLevel` | `'trace'` | Minimum level to log |
|
|
228
|
+
| `sampleRates` | `object` | all 1.0 | Per-level sample rates |
|
|
229
|
+
| `scrubPatterns` | `RegExp[]` | `[]` | Additional patterns to scrub |
|
|
230
|
+
| `batchSize` | `number` | `50` | Batch size before flush |
|
|
231
|
+
| `flushInterval` | `number` | `5000` | Flush interval in ms |
|
|
232
|
+
| `maxQueueSize` | `number` | `1000` | Max queue size |
|
|
233
|
+
|
|
130
234
|
## Framework Integrations
|
|
131
235
|
|
|
132
236
|
### Express
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
TelemetryProvider
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-NKQPBSKX.js";
|
|
4
4
|
|
|
5
5
|
// src/transport.ts
|
|
6
6
|
var Transport = class {
|
|
@@ -62,10 +62,10 @@ var Transport = class {
|
|
|
62
62
|
this.queue = [];
|
|
63
63
|
try {
|
|
64
64
|
await this.sendBatch(events);
|
|
65
|
-
} catch (
|
|
65
|
+
} catch (error2) {
|
|
66
66
|
this.queue = [...events, ...this.queue].slice(0, this.maxQueueSize);
|
|
67
67
|
if (this.debug) {
|
|
68
|
-
console.error("[Statly] Failed to send events:",
|
|
68
|
+
console.error("[Statly] Failed to send events:", error2);
|
|
69
69
|
}
|
|
70
70
|
} finally {
|
|
71
71
|
this.isSending = false;
|
|
@@ -105,13 +105,13 @@ var Transport = class {
|
|
|
105
105
|
console.log(`[Statly] Sent ${events.length} event(s)`);
|
|
106
106
|
}
|
|
107
107
|
return { success: true, status: response.status };
|
|
108
|
-
} catch (
|
|
108
|
+
} catch (error2) {
|
|
109
109
|
if (this.debug) {
|
|
110
|
-
console.error("[Statly] Network error:",
|
|
110
|
+
console.error("[Statly] Network error:", error2);
|
|
111
111
|
}
|
|
112
112
|
return {
|
|
113
113
|
success: false,
|
|
114
|
-
error:
|
|
114
|
+
error: error2 instanceof Error ? error2.message : "Network error"
|
|
115
115
|
};
|
|
116
116
|
}
|
|
117
117
|
}
|
|
@@ -178,16 +178,16 @@ var GlobalHandlers = class {
|
|
|
178
178
|
if (!this.errorCallback) {
|
|
179
179
|
return;
|
|
180
180
|
}
|
|
181
|
-
let
|
|
181
|
+
let error2;
|
|
182
182
|
if (event.reason instanceof Error) {
|
|
183
|
-
|
|
183
|
+
error2 = event.reason;
|
|
184
184
|
} else if (typeof event.reason === "string") {
|
|
185
|
-
|
|
185
|
+
error2 = new Error(event.reason);
|
|
186
186
|
} else {
|
|
187
|
-
|
|
188
|
-
|
|
187
|
+
error2 = new Error("Unhandled Promise Rejection");
|
|
188
|
+
error2.reason = event.reason;
|
|
189
189
|
}
|
|
190
|
-
this.errorCallback(
|
|
190
|
+
this.errorCallback(error2, {
|
|
191
191
|
mechanism: { type: "onunhandledrejection", handled: false }
|
|
192
192
|
});
|
|
193
193
|
};
|
|
@@ -230,13 +230,13 @@ var GlobalHandlers = class {
|
|
|
230
230
|
}
|
|
231
231
|
installOnError() {
|
|
232
232
|
this.originalOnError = window.onerror;
|
|
233
|
-
window.onerror = (message, source, lineno, colno,
|
|
233
|
+
window.onerror = (message, source, lineno, colno, error2) => {
|
|
234
234
|
if (this.originalOnError) {
|
|
235
|
-
this.originalOnError.call(window, message, source, lineno, colno,
|
|
235
|
+
this.originalOnError.call(window, message, source, lineno, colno, error2);
|
|
236
236
|
}
|
|
237
237
|
if (this.errorCallback) {
|
|
238
|
-
const errorObj =
|
|
239
|
-
if (!
|
|
238
|
+
const errorObj = error2 || new Error(String(message));
|
|
239
|
+
if (!error2 && source) {
|
|
240
240
|
errorObj.filename = source;
|
|
241
241
|
errorObj.lineno = lineno;
|
|
242
242
|
errorObj.colno = colno;
|
|
@@ -300,13 +300,12 @@ var ConsoleIntegration = class {
|
|
|
300
300
|
return;
|
|
301
301
|
}
|
|
302
302
|
this.originalMethods[level] = originalMethod;
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
self.callback({
|
|
303
|
+
console[level] = (...args) => {
|
|
304
|
+
if (this.callback) {
|
|
305
|
+
this.callback({
|
|
307
306
|
category: "console",
|
|
308
|
-
message:
|
|
309
|
-
level:
|
|
307
|
+
message: this.formatArgs(args),
|
|
308
|
+
level: this.mapLevel(level),
|
|
310
309
|
data: args.length > 1 ? { arguments: args } : void 0
|
|
311
310
|
});
|
|
312
311
|
}
|
|
@@ -400,8 +399,8 @@ var StatlyClient = class {
|
|
|
400
399
|
}
|
|
401
400
|
this.initialized = true;
|
|
402
401
|
if (this.options.autoCapture) {
|
|
403
|
-
this.globalHandlers.install((
|
|
404
|
-
this.captureError(
|
|
402
|
+
this.globalHandlers.install((error2, context) => {
|
|
403
|
+
this.captureError(error2, context);
|
|
405
404
|
});
|
|
406
405
|
}
|
|
407
406
|
if (this.options.captureConsole) {
|
|
@@ -424,15 +423,15 @@ var StatlyClient = class {
|
|
|
424
423
|
/**
|
|
425
424
|
* Capture an exception/error
|
|
426
425
|
*/
|
|
427
|
-
captureException(
|
|
426
|
+
captureException(error2, context) {
|
|
428
427
|
let errorObj;
|
|
429
|
-
if (
|
|
430
|
-
errorObj =
|
|
431
|
-
} else if (typeof
|
|
432
|
-
errorObj = new Error(
|
|
428
|
+
if (error2 instanceof Error) {
|
|
429
|
+
errorObj = error2;
|
|
430
|
+
} else if (typeof error2 === "string") {
|
|
431
|
+
errorObj = new Error(error2);
|
|
433
432
|
} else {
|
|
434
433
|
errorObj = new Error("Unknown error");
|
|
435
|
-
errorObj.originalError =
|
|
434
|
+
errorObj.originalError = error2;
|
|
436
435
|
}
|
|
437
436
|
return this.captureError(errorObj, context);
|
|
438
437
|
}
|
|
@@ -467,24 +466,24 @@ var StatlyClient = class {
|
|
|
467
466
|
* Execute a function within a trace span
|
|
468
467
|
*/
|
|
469
468
|
async trace(name, operation, tags) {
|
|
470
|
-
const { trace: traceFn } = await import("./telemetry-
|
|
469
|
+
const { trace: traceFn } = await import("./telemetry-JOMOMZ25.js");
|
|
471
470
|
return traceFn(name, operation, tags);
|
|
472
471
|
}
|
|
473
472
|
/**
|
|
474
473
|
* Internal method to capture an error
|
|
475
474
|
*/
|
|
476
|
-
captureError(
|
|
475
|
+
captureError(error2, context) {
|
|
477
476
|
if (Math.random() > this.options.sampleRate) {
|
|
478
477
|
return "";
|
|
479
478
|
}
|
|
480
479
|
const event = this.buildEvent({
|
|
481
|
-
message:
|
|
480
|
+
message: error2.message,
|
|
482
481
|
level: "error",
|
|
483
|
-
stack:
|
|
482
|
+
stack: error2.stack,
|
|
484
483
|
exception: {
|
|
485
|
-
type:
|
|
486
|
-
value:
|
|
487
|
-
stacktrace: this.parseStackTrace(
|
|
484
|
+
type: error2.name,
|
|
485
|
+
value: error2.message,
|
|
486
|
+
stacktrace: this.parseStackTrace(error2.stack)
|
|
488
487
|
},
|
|
489
488
|
extra: context
|
|
490
489
|
});
|
|
@@ -697,7 +696,7 @@ function withStatlyPagesApi(handler) {
|
|
|
697
696
|
try {
|
|
698
697
|
const result = await handler(req, res);
|
|
699
698
|
return result;
|
|
700
|
-
} catch (
|
|
699
|
+
} catch (error2) {
|
|
701
700
|
const context = {
|
|
702
701
|
request: {
|
|
703
702
|
method: req.method,
|
|
@@ -706,8 +705,8 @@ function withStatlyPagesApi(handler) {
|
|
|
706
705
|
query: req.query
|
|
707
706
|
}
|
|
708
707
|
};
|
|
709
|
-
Statly.captureException(
|
|
710
|
-
throw
|
|
708
|
+
Statly.captureException(error2, context);
|
|
709
|
+
throw error2;
|
|
711
710
|
}
|
|
712
711
|
});
|
|
713
712
|
};
|
|
@@ -733,7 +732,7 @@ function withStatly(handler) {
|
|
|
733
732
|
span.setTag("http.status_code", result.status.toString());
|
|
734
733
|
}
|
|
735
734
|
return result;
|
|
736
|
-
} catch (
|
|
735
|
+
} catch (error2) {
|
|
737
736
|
const headers = {};
|
|
738
737
|
request.headers.forEach((value, key) => {
|
|
739
738
|
headers[key] = value;
|
|
@@ -752,17 +751,17 @@ function withStatly(handler) {
|
|
|
752
751
|
} catch {
|
|
753
752
|
}
|
|
754
753
|
}
|
|
755
|
-
Statly.captureException(
|
|
756
|
-
throw
|
|
754
|
+
Statly.captureException(error2, errorContext);
|
|
755
|
+
throw error2;
|
|
757
756
|
}
|
|
758
757
|
});
|
|
759
758
|
};
|
|
760
759
|
return wrappedHandler;
|
|
761
760
|
}
|
|
762
|
-
function captureNextJsError(
|
|
763
|
-
return Statly.captureException(
|
|
761
|
+
function captureNextJsError(error2, context) {
|
|
762
|
+
return Statly.captureException(error2, {
|
|
764
763
|
...context,
|
|
765
|
-
digest:
|
|
764
|
+
digest: error2.digest,
|
|
766
765
|
source: "nextjs-error-boundary"
|
|
767
766
|
});
|
|
768
767
|
}
|
|
@@ -770,12 +769,12 @@ function withStatlyGetServerSideProps(handler) {
|
|
|
770
769
|
return async (context) => {
|
|
771
770
|
try {
|
|
772
771
|
return await handler(context);
|
|
773
|
-
} catch (
|
|
774
|
-
Statly.captureException(
|
|
772
|
+
} catch (error2) {
|
|
773
|
+
Statly.captureException(error2, {
|
|
775
774
|
source: "getServerSideProps",
|
|
776
775
|
url: context.req?.url || context.resolvedUrl
|
|
777
776
|
});
|
|
778
|
-
throw
|
|
777
|
+
throw error2;
|
|
779
778
|
}
|
|
780
779
|
};
|
|
781
780
|
}
|
|
@@ -783,12 +782,12 @@ function withStatlyGetStaticProps(handler) {
|
|
|
783
782
|
return async (context) => {
|
|
784
783
|
try {
|
|
785
784
|
return await handler(context);
|
|
786
|
-
} catch (
|
|
787
|
-
Statly.captureException(
|
|
785
|
+
} catch (error2) {
|
|
786
|
+
Statly.captureException(error2, {
|
|
788
787
|
source: "getStaticProps",
|
|
789
788
|
params: context.params
|
|
790
789
|
});
|
|
791
|
-
throw
|
|
790
|
+
throw error2;
|
|
792
791
|
}
|
|
793
792
|
};
|
|
794
793
|
}
|
|
@@ -804,12 +803,12 @@ function withStatlyServerAction(action, actionName) {
|
|
|
804
803
|
});
|
|
805
804
|
try {
|
|
806
805
|
return await action(...args);
|
|
807
|
-
} catch (
|
|
808
|
-
Statly.captureException(
|
|
806
|
+
} catch (error2) {
|
|
807
|
+
Statly.captureException(error2, {
|
|
809
808
|
source: "server-action",
|
|
810
809
|
actionName
|
|
811
810
|
});
|
|
812
|
-
throw
|
|
811
|
+
throw error2;
|
|
813
812
|
}
|
|
814
813
|
});
|
|
815
814
|
};
|
|
@@ -864,16 +863,16 @@ function statlyFastifyPlugin(fastify, options, done) {
|
|
|
864
863
|
});
|
|
865
864
|
hookDone();
|
|
866
865
|
});
|
|
867
|
-
fastify.setErrorHandler((
|
|
868
|
-
const statusCode =
|
|
866
|
+
fastify.setErrorHandler((error2, request, reply) => {
|
|
867
|
+
const statusCode = error2.statusCode || 500;
|
|
869
868
|
if (skipStatusCodes.includes(statusCode)) {
|
|
870
|
-
throw
|
|
869
|
+
throw error2;
|
|
871
870
|
}
|
|
872
|
-
if (!captureValidationErrors &&
|
|
873
|
-
throw
|
|
871
|
+
if (!captureValidationErrors && error2.validation) {
|
|
872
|
+
throw error2;
|
|
874
873
|
}
|
|
875
|
-
if (shouldCapture && !shouldCapture(
|
|
876
|
-
throw
|
|
874
|
+
if (shouldCapture && !shouldCapture(error2)) {
|
|
875
|
+
throw error2;
|
|
877
876
|
}
|
|
878
877
|
const context = {
|
|
879
878
|
request: {
|
|
@@ -886,27 +885,27 @@ function statlyFastifyPlugin(fastify, options, done) {
|
|
|
886
885
|
params: request.params
|
|
887
886
|
},
|
|
888
887
|
error: {
|
|
889
|
-
statusCode:
|
|
890
|
-
code:
|
|
888
|
+
statusCode: error2.statusCode,
|
|
889
|
+
code: error2.code
|
|
891
890
|
}
|
|
892
891
|
};
|
|
893
892
|
if (request.ip) {
|
|
894
893
|
context.ip = request.ip;
|
|
895
894
|
}
|
|
896
|
-
if (
|
|
897
|
-
context.validation =
|
|
895
|
+
if (error2.validation) {
|
|
896
|
+
context.validation = error2.validation;
|
|
898
897
|
}
|
|
899
898
|
Statly.setTag("http.method", request.method);
|
|
900
899
|
Statly.setTag("http.url", request.routerPath || request.url);
|
|
901
900
|
Statly.setTag("http.status_code", String(statusCode));
|
|
902
|
-
Statly.captureException(
|
|
903
|
-
throw
|
|
901
|
+
Statly.captureException(error2, context);
|
|
902
|
+
throw error2;
|
|
904
903
|
});
|
|
905
904
|
done();
|
|
906
905
|
}
|
|
907
906
|
var statlyPlugin = statlyFastifyPlugin;
|
|
908
907
|
function createRequestCapture(request) {
|
|
909
|
-
return (
|
|
908
|
+
return (error2, additionalContext) => {
|
|
910
909
|
const context = {
|
|
911
910
|
request: {
|
|
912
911
|
id: request.id,
|
|
@@ -916,7 +915,7 @@ function createRequestCapture(request) {
|
|
|
916
915
|
},
|
|
917
916
|
...additionalContext
|
|
918
917
|
};
|
|
919
|
-
return Statly.captureException(
|
|
918
|
+
return Statly.captureException(error2, context);
|
|
920
919
|
};
|
|
921
920
|
}
|
|
922
921
|
function sanitizeHeaders2(headers) {
|
|
@@ -966,12 +965,12 @@ function init(options) {
|
|
|
966
965
|
client = new StatlyClient(finalOptions);
|
|
967
966
|
client.init();
|
|
968
967
|
}
|
|
969
|
-
function captureException(
|
|
968
|
+
function captureException(error2, context) {
|
|
970
969
|
if (!client) {
|
|
971
970
|
console.warn("[Statly] SDK not initialized. Call Statly.init() first.");
|
|
972
971
|
return "";
|
|
973
972
|
}
|
|
974
|
-
return client.captureException(
|
|
973
|
+
return client.captureException(error2, context);
|
|
975
974
|
}
|
|
976
975
|
function captureMessage(message, level = "info") {
|
|
977
976
|
if (!client) {
|
|
@@ -1024,7 +1023,7 @@ async function close() {
|
|
|
1024
1023
|
function getClient() {
|
|
1025
1024
|
return client;
|
|
1026
1025
|
}
|
|
1027
|
-
async function
|
|
1026
|
+
async function trace2(name, operation, tags) {
|
|
1028
1027
|
if (!client) {
|
|
1029
1028
|
return operation(null);
|
|
1030
1029
|
}
|
|
@@ -1049,7 +1048,7 @@ var Statly = {
|
|
|
1049
1048
|
flush,
|
|
1050
1049
|
close,
|
|
1051
1050
|
getClient,
|
|
1052
|
-
trace,
|
|
1051
|
+
trace: trace2,
|
|
1053
1052
|
startSpan,
|
|
1054
1053
|
captureSpan
|
|
1055
1054
|
};
|
|
@@ -1093,8 +1092,8 @@ function requestHandler() {
|
|
|
1093
1092
|
}
|
|
1094
1093
|
function expressErrorHandler(options = {}) {
|
|
1095
1094
|
return (err, req, res, next) => {
|
|
1096
|
-
const
|
|
1097
|
-
if (options.shouldHandleError && !options.shouldHandleError(
|
|
1095
|
+
const error2 = err instanceof Error ? err : new Error(String(err));
|
|
1096
|
+
if (options.shouldHandleError && !options.shouldHandleError(error2)) {
|
|
1098
1097
|
return next(err);
|
|
1099
1098
|
}
|
|
1100
1099
|
const context = {
|
|
@@ -1118,7 +1117,7 @@ function expressErrorHandler(options = {}) {
|
|
|
1118
1117
|
if (req.statlyContext?.transactionName) {
|
|
1119
1118
|
Statly.setTag("transaction", req.statlyContext.transactionName);
|
|
1120
1119
|
}
|
|
1121
|
-
Statly.captureException(
|
|
1120
|
+
Statly.captureException(error2, context);
|
|
1122
1121
|
next(err);
|
|
1123
1122
|
};
|
|
1124
1123
|
}
|
|
@@ -1175,7 +1174,7 @@ export {
|
|
|
1175
1174
|
flush,
|
|
1176
1175
|
close,
|
|
1177
1176
|
getClient,
|
|
1178
|
-
trace,
|
|
1177
|
+
trace2 as trace,
|
|
1179
1178
|
startSpan,
|
|
1180
1179
|
captureSpan,
|
|
1181
1180
|
Statly
|