@forge-ops/tracker 0.1.0 → 0.1.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 +26 -28
- package/package.json +7 -3
package/README.md
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
# @forge-ops/tracker
|
|
2
2
|
|
|
3
3
|
Node.js error reporting client for a private, self-hosted [ForgeOps](../../) tracker instance.
|
|
4
|
-
Requires Node 18+ (for global `fetch`).
|
|
5
|
-
|
|
6
|
-
|
|
4
|
+
Requires Node 18+ (for global `fetch`). It captures uncaught exceptions, unhandled promise
|
|
5
|
+
rejections, and explicitly reported errors, builds a backtrace, scrubs likely PII, and delivers
|
|
6
|
+
events to ForgeOps over HTTP without blocking the request or process that raised them.
|
|
7
7
|
|
|
8
8
|
## Installation
|
|
9
9
|
|
|
@@ -76,8 +76,8 @@ try {
|
|
|
76
76
|
}
|
|
77
77
|
```
|
|
78
78
|
|
|
79
|
-
There's no
|
|
80
|
-
explicitly instead, right at the catch site:
|
|
79
|
+
There's no application-wide hook that reports an exception while still letting your own catch
|
|
80
|
+
block handle it -- report it explicitly instead, right at the catch site:
|
|
81
81
|
|
|
82
82
|
```js
|
|
83
83
|
} catch (err) {
|
|
@@ -108,35 +108,33 @@ dropped rather than thrown, so a broken or unreachable tracker can never take do
|
|
|
108
108
|
|
|
109
109
|
## Delivery: an async loop, not a thread
|
|
110
110
|
|
|
111
|
-
`DeliveryQueue` here isn't a background *thread*
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
forked
|
|
111
|
+
`DeliveryQueue` here isn't a background *thread* -- Node is single-threaded. But a Node process is
|
|
112
|
+
long-running across many requests, so an async processing loop on the event loop is the natural
|
|
113
|
+
substitute: `push()` returns immediately, and delivery happens via non-blocking `fetch()` calls
|
|
114
|
+
without ever blocking the request that pushed it. The loop starts lazily, on first push, not at
|
|
115
|
+
import time -- Node's `cluster` module can fork worker processes *after* the application has
|
|
116
|
+
already loaded, and an eagerly-started loop would be left dead in every forked child; starting
|
|
117
|
+
fresh on first push means each forked worker gets its own live loop regardless of when it was
|
|
118
|
+
forked relative to import.
|
|
119
119
|
|
|
120
120
|
## `in_app` backtrace frames
|
|
121
121
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
stack
|
|
133
|
-
|
|
134
|
-
*construction* time, not at `throw` time, so there's no "empty backtrace" case for an exception
|
|
135
|
-
that's constructed but never thrown.
|
|
122
|
+
Node runs interpreted directly from real `.js` files on disk, so file-path matching against
|
|
123
|
+
`Configuration#appRoot` is a straightforward prefix comparison against those on-disk paths.
|
|
124
|
+
Defaults to the current working directory; set it explicitly if that doesn't match your app's
|
|
125
|
+
actual layout. `node_modules` frames are never marked `in_app`, regardless of `appRoot`; Node's own
|
|
126
|
+
internal modules (the `node:` scheme) never match a real `appRoot` prefix either, so they don't
|
|
127
|
+
need special-casing.
|
|
128
|
+
|
|
129
|
+
Backtrace parsing is a regex over `Error#stack`, a plain string in V8 rather than a structured
|
|
130
|
+
object -- verified directly against real captured stack traces, both synchronous and `async`,
|
|
131
|
+
named and anonymous frames, before relying on it. One quirk worth knowing: V8 captures an Error's
|
|
132
|
+
stack at *construction* time, not at `throw` time, so there's no "empty backtrace" case for an
|
|
133
|
+
exception that's constructed but never thrown.
|
|
136
134
|
|
|
137
135
|
## PII scrubbing
|
|
138
136
|
|
|
139
|
-
|
|
137
|
+
By default, the message, backtrace, and any context/tags you attach are scanned
|
|
140
138
|
for likely personal data -- email addresses, formatted SSNs/credit cards, known API key/token
|
|
141
139
|
formats, and anything under a suspiciously-named key (`password`, `apiKey`, `ssn`, and similar) --
|
|
142
140
|
and redacted before the payload ever leaves this process. ForgeOps itself scrubs again on arrival
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@forge-ops/tracker",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.1",
|
|
4
4
|
"description": "ForgeOps error tracking client: captures unhandled exceptions (Express/Fastify integration, plus explicit capture anywhere else) and delivers them to a ForgeOps instance over HTTP.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "src/index.js",
|
|
@@ -31,8 +31,12 @@
|
|
|
31
31
|
"fastify": ">=4"
|
|
32
32
|
},
|
|
33
33
|
"peerDependenciesMeta": {
|
|
34
|
-
"express": {
|
|
35
|
-
|
|
34
|
+
"express": {
|
|
35
|
+
"optional": true
|
|
36
|
+
},
|
|
37
|
+
"fastify": {
|
|
38
|
+
"optional": true
|
|
39
|
+
}
|
|
36
40
|
},
|
|
37
41
|
"devDependencies": {
|
|
38
42
|
"@eslint/js": "^10.0.0",
|