Repository navigation
Closed
Labels
bugSomething isn't workingSomething isn't working
Description
Test I ran
node abort_errors.ts
slice run abort_errors.ts --allow-net=127.0.0.1:1abort_errors.ts
import { setTimeout as sleep } from "node:timers/promises";
const show = async (k: string, f: () => unknown) => { let v; try { v = await Promise.race([Promise.resolve().then(f), new Promise((r) => setTimeout(() => r("NEVER SETTLED (2000 ms)"), 2000))]); } catch (e: any) { v = "THROWS " + e.name + ": " + String(e.message).slice(0, 100); } console.log(k.padEnd(52) + JSON.stringify(v)); };
(async () => {
await show("typeof DOMException", () => typeof DOMException);
const ts = AbortSignal.timeout(5); await sleep(20);
await show("AbortSignal.timeout(5).reason [name, code]", () => [ts.aborted, ts.reason?.name, ts.reason?.code]);
const ac = new AbortController(); ac.abort();
await show("controller.abort() default reason [name, code]", () => [ac.signal.reason?.name, ac.signal.reason?.code]);
await show("signal.throwIfAborted() throws error named", () => { try { ac.signal.throwIfAborted(); return "no throw"; } catch (e: any) { return e.name; } });
await show("timers/promises setTimeout aborted [name, code]", async () => { const ac2 = new AbortController(); const p = sleep(1000, "x", { signal: ac2.signal }).catch((e) => [e.name, e.code]); ac2.abort(); return p; });
await show("fetch(url, {signal: aborted}) rejects with", () => { const ac3 = new AbortController(); ac3.abort(); return fetch("http://127.0.0.1:1/", { signal: ac3.signal }).then(() => "resolved", (e) => e.name); });
await show("new DOMException('m','AbortError') [name, code]", () => { const e = new DOMException("m", "AbortError"); return [e.name, e.code, e instanceof Error]; });
})();Result
Node v24.22.2:
typeof DOMException "function"
AbortSignal.timeout(5).reason [name, code] [true,"TimeoutError",23]
controller.abort() default reason [name, code] ["AbortError",20]
signal.throwIfAborted() throws error named "AbortError"
timers/promises setTimeout aborted [name, code] ["AbortError","ABORT_ERR"]
fetch(url, {signal: aborted}) rejects with "AbortError"
new DOMException('m','AbortError') [name, code] ["AbortError",20,true]
Slice v0.10.7:
typeof DOMException "undefined"
AbortSignal.timeout(5).reason [name, code] [true,"Error",null]
controller.abort() default reason [name, code] ["Error",null]
signal.throwIfAborted() throws error named "Error"
timers/promises setTimeout aborted [name, code] ["Error",null]
fetch(url, {signal: aborted}) rejects with "Error"
new DOMException('m','AbortError') [name, code] "THROWS ReferenceError: DOMException is not defined"
What is wrong
globalThis.DOMExceptiondoes not exist (COMPATIBILITY.md, "Events & Signals": "…AbortSignal.any(signals), andDOMException").- Every abort path produces an error whose
nameis"Error":controller.abort()'s default reason,signal.throwIfAborted(),AbortSignal.timeout()(should beTimeoutError),timers/promisescancellation and an abortedfetch().
The usual way to tell a cancellation from a failure is if (err.name === "AbortError") return; (or err.code === "ABORT_ERR"). On Slice that check never matches, so cancelled requests are handled as real errors.
Environment
- Slice
v0.10.7, commitea7c70c, built withcargo +1.96.0 build --release --locked --bin slice - Reference: Node.js
v24.22.2(same script, same machine) - Ubuntu 26.04, Linux 7.0, x86_64
- The same output is produced by the
v0.10.5tag, so this is not a regression in 0.10.6/0.10.7.
Metadata
Metadata
Assignees
Labels
bugSomething isn't workingSomething isn't working
Activity
siktec-lab commentedon Nov 11, 2026
Addressed in #67 (�0.10.11): added the global DOMException constructor with W3C legacy error codes (ABORT_ERR = 20, TIMEOUT_ERR = 23, DATA_CLONE_ERR = 25, etc.), updated AbortSignal.abort(), AbortController#abort(), AbortSignal.timeout(), and etch() to produce DOMException instances (while preserving custom abort reasons), and updated
ode:timers/promises abort rejections to attach
ame = 'AbortError', code = 'ABORT_ERR', and cause = signal.reason.