@snokam/application-insights 1.3.2 → 1.3.3
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/CHANGELOG.md +7 -0
- package/package.json +1 -1
- package/src/server.ts +6 -2
- package/src/telemetry/requestNoise.test.ts +73 -0
- package/src/telemetry/requestNoise.ts +27 -0
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,13 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
## [1.3.3](https://github.com/snokam/components/compare/%40snokam%2Fapplication-insights%401.3.1...%40snokam%2Fapplication-insights%401.3.3) (2026-11-11)
|
|
7
|
+
|
|
8
|
+
### Bug Fixes
|
|
9
|
+
|
|
10
|
+
- error pipeline noise filters, burst alerts, telemetry roles and per-activity fan-out logs ([#3496](https://github.com/snokam/components/issues/3496)) ([e41e941](https://github.com/snokam/components/commit/e41e9415a899f075585923989c87b2ea4f27f273))
|
|
11
|
+
- **web:** prod error cluster: story swiper crash, scanner noise, stale-deployment reload ([#3530](https://github.com/snokam/components/issues/3530)) ([f3a6c67](https://github.com/snokam/components/commit/f3a6c6713acfda5e087c4ed74881ecb95f0b76b1))
|
|
12
|
+
|
|
6
13
|
## [1.3.2](https://github.com/snokam/components/compare/%40snokam%2Fapplication-insights%401.3.1...%40snokam%2Fapplication-insights%401.3.2) (2026-11-10)
|
|
7
14
|
|
|
8
15
|
### Bug Fixes
|
package/package.json
CHANGED
package/src/server.ts
CHANGED
|
@@ -5,6 +5,7 @@ import {
|
|
|
5
5
|
type ServerError,
|
|
6
6
|
} from "./telemetry/exceptionEnvelope";
|
|
7
7
|
import { operationIdFrom } from "./telemetry/operationId";
|
|
8
|
+
import { isRequestNoise } from "./telemetry/requestNoise";
|
|
8
9
|
|
|
9
10
|
type ErrorRequest = {
|
|
10
11
|
path?: string;
|
|
@@ -62,13 +63,16 @@ export async function onRequestError(
|
|
|
62
63
|
crypto.randomUUID().replaceAll("-", "")
|
|
63
64
|
),
|
|
64
65
|
};
|
|
65
|
-
|
|
66
|
-
|
|
66
|
+
const noise = isRequestNoise(error, location);
|
|
67
|
+
const log = noise ? console.warn : console.error;
|
|
68
|
+
log(
|
|
69
|
+
noise ? "[server-request-noise]" : "[server-error]",
|
|
67
70
|
JSON.stringify({
|
|
68
71
|
...location,
|
|
69
72
|
message: error instanceof Error ? error.message : String(error),
|
|
70
73
|
stack: error instanceof Error ? error.stack : undefined,
|
|
71
74
|
})
|
|
72
75
|
);
|
|
76
|
+
if (noise) return;
|
|
73
77
|
await trackException({ error, location });
|
|
74
78
|
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { test } from "node:test";
|
|
2
|
+
import assert from "node:assert/strict";
|
|
3
|
+
import { isRequestNoise } from "./requestNoise.ts";
|
|
4
|
+
|
|
5
|
+
const page = {
|
|
6
|
+
method: "POST",
|
|
7
|
+
path: "/",
|
|
8
|
+
routePath: "/(public)/www/[host]/page",
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
test("a server action from another deployment or a scanner is not a server error", () => {
|
|
12
|
+
const error = new Error(
|
|
13
|
+
"Failed to find Server Action. This request might be from an older or newer deployment.\nRead more: https://nextjs.org/docs/messages/failed-to-find-server-action"
|
|
14
|
+
);
|
|
15
|
+
|
|
16
|
+
assert.equal(isRequestNoise(error, page), true);
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
test("a visitor who leaves before the page finished streaming is not a server error", () => {
|
|
20
|
+
const error = new Error("The destination stream closed early.");
|
|
21
|
+
|
|
22
|
+
assert.equal(
|
|
23
|
+
isRequestNoise(error, {
|
|
24
|
+
method: "GET",
|
|
25
|
+
path: "/?_rsc=abc",
|
|
26
|
+
routePath: "/minside/[host]",
|
|
27
|
+
}),
|
|
28
|
+
true
|
|
29
|
+
);
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
test("a server action posted to a page that does not exist is not a server error", () => {
|
|
33
|
+
const error = Object.assign(
|
|
34
|
+
new Error(
|
|
35
|
+
"Invariant: Expected RSC response, got text/plain. This is a bug in Next.js."
|
|
36
|
+
),
|
|
37
|
+
{ name: "InvariantError" }
|
|
38
|
+
);
|
|
39
|
+
|
|
40
|
+
assert.equal(
|
|
41
|
+
isRequestNoise(error, {
|
|
42
|
+
method: "POST",
|
|
43
|
+
path: "/login",
|
|
44
|
+
routePath: "/_not-found/page",
|
|
45
|
+
}),
|
|
46
|
+
true
|
|
47
|
+
);
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
test("the same invariant on a real page is still reported", () => {
|
|
51
|
+
const error = new Error(
|
|
52
|
+
"Invariant: Expected RSC response, got text/plain. This is a bug in Next.js."
|
|
53
|
+
);
|
|
54
|
+
|
|
55
|
+
assert.equal(isRequestNoise(error, page), false);
|
|
56
|
+
assert.equal(
|
|
57
|
+
isRequestNoise(error, { method: "GET", routePath: "/_not-found/page" }),
|
|
58
|
+
false
|
|
59
|
+
);
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
test("failed api calls and render crashes are still reported", () => {
|
|
63
|
+
const failed = Object.assign(new Error("Response returned an error code"), {
|
|
64
|
+
name: "ResponseError",
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
assert.equal(isRequestNoise(failed, page), false);
|
|
68
|
+
assert.equal(
|
|
69
|
+
isRequestNoise(new ReferenceError("TRACK_BAR is not defined"), page),
|
|
70
|
+
false
|
|
71
|
+
);
|
|
72
|
+
assert.equal(isRequestNoise("boom", page), false);
|
|
73
|
+
});
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { RequestLocation } from "./exceptionEnvelope";
|
|
2
|
+
|
|
3
|
+
const UNKNOWN_SERVER_ACTION = "Failed to find Server Action";
|
|
4
|
+
const CLIENT_LEFT = "The destination stream closed early";
|
|
5
|
+
const ACTION_ON_MISSING_PAGE = "Expected RSC response, got text/plain";
|
|
6
|
+
const NOT_FOUND_ROUTE = "/_not-found/page";
|
|
7
|
+
|
|
8
|
+
function messageOf(error: unknown) {
|
|
9
|
+
return error instanceof Error ? error.message : String(error);
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
function isActionOnMissingPage(message: string, location: RequestLocation) {
|
|
13
|
+
return (
|
|
14
|
+
message.includes(ACTION_ON_MISSING_PAGE) &&
|
|
15
|
+
location.method === "POST" &&
|
|
16
|
+
location.routePath === NOT_FOUND_ROUTE
|
|
17
|
+
);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export function isRequestNoise(error: unknown, location: RequestLocation) {
|
|
21
|
+
const message = messageOf(error);
|
|
22
|
+
return (
|
|
23
|
+
message.startsWith(UNKNOWN_SERVER_ACTION) ||
|
|
24
|
+
message.startsWith(CLIENT_LEFT) ||
|
|
25
|
+
isActionOnMissingPage(message, location)
|
|
26
|
+
);
|
|
27
|
+
}
|