AbortSignal throwIfAborted

signal.throwIfAborted() API throws signal’s abort reason, if signal’s AbortController has signaled to abort; otherwise, does nothing.

Quick Examples:

const signal = AbortSignal.abort(new Error("💣"))
/*AbortSignal {aborted: true, reason: Error: 💣
at <anonymous>:1:28, onabort: null} */

signal.throwIfAborted()

/*
VM74:1 Uncaught Error: 💣
at <anonymous>:1:28
*/
// From the issues
function animationFrame(abortSignal) {
return new Promise((resolve, reject) => {
abortSignal?.throwIfAborted();
const frameRequest = requestAnimationFrame(time => resolve(time));
abortSignal?.addEventListener("abort", () => {
cancelAnimationFrame(frameRequest);
reject(new AbortError());
}, { once: true });
});
}
// From the spec
async function waitForCondition(func, targetValue, { signal } = {}) {
while (true) {
signal?.throwIfAborted();

const result = await func();
if (result === targetValue) {
return;
}
}
}

Signal-handling methods can use throwIfAborted API to check a signal's abort status and propagate the abort reason, ex: async activities that might affect a signal's state.

Browser implementation:

Below is the crux from Firefox's implementation.

// https://dom.spec.whatwg.org/#dom-abortsignal-throwifaborted
void AbortSignal::ThrowIfAborted(JSContext* aCx, ErrorResult& aRv) {
aRv.MightThrowJSException();
if (Aborted()) {
JS::Rooted<JS::Value> reason(aCx);
GetReason(aCx, &reason);
aRv.ThrowJSException(aCx, reason);
}
}

Safari is pretty similar:

void AbortSignal::throwIfAborted(JSC::JSGlobalObject& lexicalGlobalObject)
{
if (!aborted())
return;

auto& vm = lexicalGlobalObject.vm();
auto scope = DECLARE_THROW_SCOPE(vm);
throwException(&lexicalGlobalObject, scope, m_reason);
}

Chrome

void AbortSignal::throwIfAborted(ScriptState* script_state,
ExceptionState& exception_state) const {
if (!aborted())
return;
exception_state.RethrowV8Exception(reason(script_state).V8Value());
}

throwIfAborted() should:

Feel free to share this article. You may as well ping me on Twitter.

Published