nuxt-error-tracker 0.1.4 → 0.1.6
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 +31 -1
- package/dist/module.json +1 -1
- package/dist/module.mjs +5 -8
- package/dist/runtime/ingest.codec.js +51 -57
- package/dist/runtime/plugin.server.d.ts +2 -0
- package/dist/runtime/plugin.server.js +9 -0
- package/package.json +1 -4
package/README.md
CHANGED
|
@@ -23,6 +23,32 @@ npm i nuxt-error-tracker
|
|
|
23
23
|
# or: bun add nuxt-error-tracker
|
|
24
24
|
```
|
|
25
25
|
|
|
26
|
+
## Getting your keys
|
|
27
|
+
|
|
28
|
+
The module needs two values — an **ingest endpoint** and a **public key**. Both
|
|
29
|
+
come from your Observer dashboard. Everything after step 4 is what you paste into
|
|
30
|
+
the app; from then on your errors show up in the same dashboard.
|
|
31
|
+
|
|
32
|
+
1. Open the dashboard at `https://<your-observer-host>/dashboard`.
|
|
33
|
+
2. **Create account** — enter an email and a password (min 8 chars), submit. You
|
|
34
|
+
stay signed in via a secure cookie.
|
|
35
|
+
3. Click **New project**, give it a name (e.g. `my-app`), and optionally list the
|
|
36
|
+
origins your site runs on (comma-separated, e.g. `https://my-app.com,
|
|
37
|
+
http://localhost:3000`). Empty = accept any origin. This is the server-side
|
|
38
|
+
allowlist — requests from other origins are rejected.
|
|
39
|
+
4. The project now shows a **public key** (`pk_…`) and a ready-made
|
|
40
|
+
`nuxt.config` snippet. Use **Copy key** / **Copy config**.
|
|
41
|
+
5. The **endpoint** is your host + `/v1/ingest`, i.e.
|
|
42
|
+
`https://<your-observer-host>/v1/ingest`.
|
|
43
|
+
|
|
44
|
+
Then configure the package ([Setup](#setup)) and deploy. Captured errors appear
|
|
45
|
+
under that project in the dashboard — open **Logs** on the project to browse
|
|
46
|
+
them, with stack traces, recent occurrences and the breadcrumb trail.
|
|
47
|
+
|
|
48
|
+
> Origins matter: if you set an allowlist, it must include every origin your app
|
|
49
|
+
> is served from (prod domains **and** `http://localhost:3000` for local dev),
|
|
50
|
+
> or the browser's requests get a 401.
|
|
51
|
+
|
|
26
52
|
## Setup
|
|
27
53
|
|
|
28
54
|
Add the module and point it at your ingest endpoint with your project's public
|
|
@@ -102,7 +128,7 @@ const { $trackError, $addBreadcrumb } = useNuxtApp()
|
|
|
102
128
|
|
|
103
129
|
// Report a handled error yourself
|
|
104
130
|
try {
|
|
105
|
-
await
|
|
131
|
+
await mayFail()
|
|
106
132
|
} catch (e) {
|
|
107
133
|
$trackError(e)
|
|
108
134
|
}
|
|
@@ -116,6 +142,10 @@ $addBreadcrumb({
|
|
|
116
142
|
})
|
|
117
143
|
```
|
|
118
144
|
|
|
145
|
+
Both helpers are always callable. Real capture happens **client-side only**; on
|
|
146
|
+
the server (SSR — e.g. top-level `<script setup>`) they are safe no-ops, so
|
|
147
|
+
calling them never throws.
|
|
148
|
+
|
|
119
149
|
## What gets sent
|
|
120
150
|
|
|
121
151
|
Per error: `message`, `stack`, `source` (`vue` | `window` | `promise` |
|
package/dist/module.json
CHANGED
package/dist/module.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { defineNuxtModule,
|
|
1
|
+
import { defineNuxtModule, createResolver, addPlugin } from '@nuxt/kit';
|
|
2
2
|
|
|
3
3
|
function posInt(value, fallback) {
|
|
4
4
|
const n = Number(value);
|
|
@@ -37,14 +37,11 @@ const module = defineNuxtModule({
|
|
|
37
37
|
// Server DTO caps at 50 breadcrumbs — stay at or below.
|
|
38
38
|
maxBreadcrumbs: Math.min(posInt(options.maxBreadcrumbs, 30), 50)
|
|
39
39
|
};
|
|
40
|
-
extendViteConfig((config) => {
|
|
41
|
-
config.optimizeDeps ||= {};
|
|
42
|
-
config.optimizeDeps.include ||= [];
|
|
43
|
-
if (!config.optimizeDeps.include.includes("protobufjs")) {
|
|
44
|
-
config.optimizeDeps.include.push("protobufjs");
|
|
45
|
-
}
|
|
46
|
-
});
|
|
47
40
|
const resolver = createResolver(import.meta.url);
|
|
41
|
+
addPlugin({
|
|
42
|
+
src: resolver.resolve("./runtime/plugin.server"),
|
|
43
|
+
mode: "server"
|
|
44
|
+
});
|
|
48
45
|
addPlugin({
|
|
49
46
|
src: resolver.resolve("./runtime/plugin.client"),
|
|
50
47
|
mode: "client"
|
|
@@ -1,37 +1,24 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
string timestamp = 5;
|
|
10
|
-
string data = 6;
|
|
11
|
-
}
|
|
12
|
-
message Error {
|
|
13
|
-
string message = 1;
|
|
14
|
-
string stack = 2;
|
|
15
|
-
string source = 3;
|
|
16
|
-
string url = 4;
|
|
17
|
-
string route = 5;
|
|
18
|
-
string userId = 6;
|
|
19
|
-
string appVersion = 7;
|
|
20
|
-
string device = 8;
|
|
21
|
-
string occurredAt = 9;
|
|
22
|
-
repeated Breadcrumb breadcrumbs = 10;
|
|
1
|
+
const textEncoder = new TextEncoder();
|
|
2
|
+
function pushVarint(out, value) {
|
|
3
|
+
let v = value >>> 0;
|
|
4
|
+
while (v > 127) {
|
|
5
|
+
out.push(v & 127 | 128);
|
|
6
|
+
v >>>= 7;
|
|
7
|
+
}
|
|
8
|
+
out.push(v);
|
|
23
9
|
}
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
10
|
+
function pushLenField(out, fieldNo, bytes) {
|
|
11
|
+
pushVarint(out, fieldNo << 3 | 2);
|
|
12
|
+
pushVarint(out, bytes.length);
|
|
13
|
+
for (let i = 0; i < bytes.length; i++) out.push(bytes[i]);
|
|
28
14
|
}
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
15
|
+
function pushString(out, fieldNo, value) {
|
|
16
|
+
if (!value) return;
|
|
17
|
+
const encoded = textEncoder.encode(value);
|
|
18
|
+
pushVarint(out, fieldNo << 3 | 2);
|
|
19
|
+
pushVarint(out, encoded.length);
|
|
20
|
+
for (let i = 0; i < encoded.length; i++) out.push(encoded[i]);
|
|
32
21
|
}
|
|
33
|
-
`;
|
|
34
|
-
const Batch = protobuf.parse(INGEST_PROTO).root.lookupType("Batch");
|
|
35
22
|
function jsonStr(v) {
|
|
36
23
|
if (v === void 0 || v === null) return "";
|
|
37
24
|
try {
|
|
@@ -40,31 +27,38 @@ function jsonStr(v) {
|
|
|
40
27
|
return "";
|
|
41
28
|
}
|
|
42
29
|
}
|
|
30
|
+
function encodeBreadcrumb(c) {
|
|
31
|
+
const out = [];
|
|
32
|
+
pushString(out, 1, c.type ?? "");
|
|
33
|
+
pushString(out, 2, c.category ?? "");
|
|
34
|
+
pushString(out, 3, c.message ?? "");
|
|
35
|
+
pushString(out, 4, c.level ?? "");
|
|
36
|
+
pushString(out, 5, c.timestamp ?? "");
|
|
37
|
+
pushString(out, 6, jsonStr(c.data));
|
|
38
|
+
return out;
|
|
39
|
+
}
|
|
40
|
+
function encodeError(e) {
|
|
41
|
+
const out = [];
|
|
42
|
+
pushString(out, 1, e.message);
|
|
43
|
+
pushString(out, 2, e.stack);
|
|
44
|
+
pushString(out, 3, e.source);
|
|
45
|
+
pushString(out, 4, e.url);
|
|
46
|
+
pushString(out, 5, e.route);
|
|
47
|
+
pushString(out, 9, e.occurredAt);
|
|
48
|
+
for (const c of e.breadcrumbs ?? []) {
|
|
49
|
+
pushLenField(out, 10, encodeBreadcrumb(c));
|
|
50
|
+
}
|
|
51
|
+
return out;
|
|
52
|
+
}
|
|
43
53
|
export function encodeBatch(body) {
|
|
44
|
-
const
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
url: e.url,
|
|
55
|
-
route: e.route,
|
|
56
|
-
appVersion: "",
|
|
57
|
-
device: "",
|
|
58
|
-
occurredAt: e.occurredAt,
|
|
59
|
-
breadcrumbs: (e.breadcrumbs ?? []).map((c) => ({
|
|
60
|
-
type: c.type ?? "",
|
|
61
|
-
category: c.category ?? "",
|
|
62
|
-
message: c.message ?? "",
|
|
63
|
-
level: c.level ?? "",
|
|
64
|
-
timestamp: c.timestamp ?? "",
|
|
65
|
-
data: jsonStr(c.data)
|
|
66
|
-
}))
|
|
67
|
-
}))
|
|
68
|
-
};
|
|
69
|
-
return Batch.encode(Batch.fromObject(message)).finish();
|
|
54
|
+
const out = [];
|
|
55
|
+
const meta = [];
|
|
56
|
+
pushString(meta, 1, jsonStr(body.meta.device));
|
|
57
|
+
pushString(meta, 2, body.meta.userId ?? "");
|
|
58
|
+
pushString(meta, 3, body.meta.appVersion ?? "");
|
|
59
|
+
pushLenField(out, 1, meta);
|
|
60
|
+
for (const e of body.errors) {
|
|
61
|
+
pushLenField(out, 2, encodeError(e));
|
|
62
|
+
}
|
|
63
|
+
return new Uint8Array(out);
|
|
70
64
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nuxt-error-tracker",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.6",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": {
|
|
@@ -19,9 +19,6 @@
|
|
|
19
19
|
"build": "nuxt-module-build build",
|
|
20
20
|
"prepublishOnly": "nuxt-module-build build"
|
|
21
21
|
},
|
|
22
|
-
"dependencies": {
|
|
23
|
-
"protobufjs": "^8.6.6"
|
|
24
|
-
},
|
|
25
22
|
"peerDependencies": {
|
|
26
23
|
"@nuxt/kit": "^3.14.0 || ^4.0.0"
|
|
27
24
|
},
|