@celestia-island/hikari 0.41.1 → 0.41.2
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/package.json
CHANGED
|
@@ -125,6 +125,48 @@ describe("createErrorReporting", () => {
|
|
|
125
125
|
expect(overlayHost()).toBeNull();
|
|
126
126
|
});
|
|
127
127
|
|
|
128
|
+
it("stays up for cross-origin-masked window errors", async () => {
|
|
129
|
+
const warn = vi.spyOn(console, "warn").mockImplementation(() => {});
|
|
130
|
+
const error = vi.spyOn(console, "error").mockImplementation(() => {});
|
|
131
|
+
// Earlier tests in this file spy the same methods without restoring;
|
|
132
|
+
// clear the accumulated calls so the assertions see only this test's.
|
|
133
|
+
warn.mockClear();
|
|
134
|
+
error.mockClear();
|
|
135
|
+
installPlugin();
|
|
136
|
+
|
|
137
|
+
// The masking signature: details withheld (error == null) because the
|
|
138
|
+
// thrower is foreign-origin code (extension / userscript), message
|
|
139
|
+
// pinned to "Script error." by every Chromium/Gecko/WebKit build.
|
|
140
|
+
window.dispatchEvent(new ErrorEvent("error", { message: "Script error.", error: null }));
|
|
141
|
+
await nextTick();
|
|
142
|
+
expect(overlayHost()).toBeNull();
|
|
143
|
+
expect(warn).toHaveBeenCalled();
|
|
144
|
+
expect(error).not.toHaveBeenCalled();
|
|
145
|
+
|
|
146
|
+
// The bare-spelling variant is masked the same way.
|
|
147
|
+
window.dispatchEvent(new ErrorEvent("error", { message: "Script error", error: null }));
|
|
148
|
+
await nextTick();
|
|
149
|
+
expect(overlayHost()).toBeNull();
|
|
150
|
+
|
|
151
|
+
clearGlobalError();
|
|
152
|
+
warn.mockRestore();
|
|
153
|
+
error.mockRestore();
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
it("still reports detail-less window errors that are not masked", async () => {
|
|
157
|
+
vi.spyOn(console, "error").mockImplementation(() => {});
|
|
158
|
+
installPlugin();
|
|
159
|
+
|
|
160
|
+
// error == null with a real message is a script error the browser DID
|
|
161
|
+
// describe — that stays reportable.
|
|
162
|
+
window.dispatchEvent(
|
|
163
|
+
new ErrorEvent("error", { message: "Uncaught SyntaxError: unexpected token", error: null }),
|
|
164
|
+
);
|
|
165
|
+
await nextTick();
|
|
166
|
+
expect(overlayHost()!.querySelector(".hk-error-landing__desc")!.textContent)
|
|
167
|
+
.toBe("Uncaught SyntaxError: unexpected token");
|
|
168
|
+
});
|
|
169
|
+
|
|
128
170
|
it("chains a pre-existing app errorHandler", () => {
|
|
129
171
|
vi.spyOn(console, "error").mockImplementation(() => {});
|
|
130
172
|
const previous = vi.fn();
|
|
@@ -87,6 +87,21 @@ function installWindowHooks(options: HkErrorReportingOptions): void {
|
|
|
87
87
|
const onError = (event: ErrorEvent) => {
|
|
88
88
|
// Resource-load failures never reach here (no capture phase); script
|
|
89
89
|
// errors always carry `error` or at least a `message`.
|
|
90
|
+
//
|
|
91
|
+
// Cross-origin-masked script errors arrive as `message: "Script
|
|
92
|
+
// error."` with a null `error` object: the browser withholds the
|
|
93
|
+
// details precisely because the thrower is NOT this origin's code
|
|
94
|
+
// (browser extensions / userscripts are the usual sources). A
|
|
95
|
+
// synthetic record for one would carry zero actionable detail and a
|
|
96
|
+
// stack pointing at this very handler, while the takeover rips the
|
|
97
|
+
// host app away from the user for noise it did not produce — log
|
|
98
|
+
// and stay up instead (chest demo report 2026-09-10: tapping the
|
|
99
|
+
// wallpaper preview in a userscript-capable mobile browser nuked
|
|
100
|
+
// the session with such a masked event).
|
|
101
|
+
if (event.error == null && /^script error\.?$/i.test(event.message)) {
|
|
102
|
+
console.warn("[hikari:error-reporting] ignored a cross-origin-masked script error");
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
90
105
|
const err = event.error ?? new Error(event.message || "Unknown script error");
|
|
91
106
|
if (reportError(err, "window")) ensureOverlayMounted();
|
|
92
107
|
};
|