64 lines
2.3 KiB
TypeScript
64 lines
2.3 KiB
TypeScript
import { expect, test } from "bun:test";
|
|
import { tempDir } from "harness";
|
|
|
|
test("HTMLRewriter should not crash when element handler throws an exception - issue #21680", async () => {
|
|
// The most important test: ensure the original crashing case from the GitHub issue doesn't crash
|
|
// This was the exact case from the issue that caused "ASSERTION FAILED: Unexpected exception observed"
|
|
|
|
// Create a minimal HTML file for testing
|
|
using dir = tempDir("htmlrewriter-crash-test", {
|
|
"min.html": "<script></script>",
|
|
});
|
|
|
|
// Original failing case: this should not crash the process
|
|
const rewriter = new HTMLRewriter().on("script", {
|
|
element(a) {
|
|
throw new Error("abc");
|
|
},
|
|
});
|
|
const res = rewriter.transform(new Response(Bun.file(`${dir}/min.html`)));
|
|
// The important thing is it doesn't crash; the handler's error surfaces on
|
|
// the output body. Await it so the file read completes before `dir` is
|
|
// disposed.
|
|
await expect(res.text()).rejects.toThrow("abc");
|
|
|
|
// Test with Response containing string content. A `Response` input surfaces
|
|
// the handler's error on the output body rather than throwing from
|
|
// `transform()`; the point of this test is that neither crashes.
|
|
const rewriter2 = new HTMLRewriter().on("script", {
|
|
element(a) {
|
|
throw new Error("response test");
|
|
},
|
|
});
|
|
await expect(rewriter2.transform(new Response("<script></script>")).text()).rejects.toThrow("response test");
|
|
});
|
|
|
|
test("HTMLRewriter exception handling should not break normal operation", () => {
|
|
// Ensure that after an exception occurs, the rewriter still works normally
|
|
let normalCallCount = 0;
|
|
|
|
// First, trigger an exception
|
|
try {
|
|
const rewriter = new HTMLRewriter().on("div", {
|
|
element(element) {
|
|
throw new Error("test error");
|
|
},
|
|
});
|
|
rewriter.transform(new Response("<div>test</div>"));
|
|
} catch (e) {
|
|
// Expected to throw
|
|
}
|
|
|
|
// Then ensure normal operation still works
|
|
const rewriter2 = new HTMLRewriter().on("div", {
|
|
element(element) {
|
|
normalCallCount++;
|
|
element.setInnerContent("replaced");
|
|
},
|
|
});
|
|
|
|
const result = rewriter2.transform(new Response("<div>original</div>"));
|
|
expect(normalCallCount).toBe(1);
|
|
// The transform should complete successfully without throwing
|
|
});
|