{"record":{"id":"f3e88f0d3be22476","repo":"denoland/deno","slug":"aborterror","errorCode":"AbortError","errorMessage":"The lock request was aborted","messagePattern":"The lock request was aborted","errorType":"exception","errorClass":"DOMException","httpStatus":null,"severity":"error","filePath":"ext/web/locks.js","lineNumber":202,"sourceCode":"      if (options.signal) {\n        const onAbort = () => op_lock_manager_cancel(rid);\n        options.signal.addEventListener(\"abort\", onAbort, { once: true });\n        try {\n          heldRid = await op_lock_manager_await_lock(rid);\n        } finally {\n          options.signal.removeEventListener(\"abort\", onAbort);\n        }\n        if (heldRid == null) {\n          throw options.signal.reason ??\n            new DOMException(\n              \"The lock request was aborted\",\n              \"AbortError\",\n            );\n        }\n      } else {\n        heldRid = await op_lock_manager_await_lock(rid);\n        if (heldRid == null) {\n          throw new DOMException(\n            \"The lock request was aborted\",\n            \"AbortError\",\n          );\n        }\n      }\n    }\n\n    try {\n      const lock = webidl.createBranded(Lock);\n      lock[_name] = name;\n      lock[_mode] = options.mode;\n      // Run the callback while concurrently watching for the lock being\n      // stolen. Awaiting the steal op also keeps the event loop alive for as\n      // long as the lock is held.\n      const callbackPromise = (async () => await callback(lock))();\n      const stolen = await SafePromiseRace([\n        op_lock_manager_await_steal(heldRid),\n        PromisePrototypeThen(callbackPromise, () => false),","sourceCodeStart":184,"sourceCodeEnd":220,"githubUrl":"https://github.com/denoland/deno/blob/9ad36f7a2cce60488e6ec52283efb32efddaf93a/ext/web/locks.js#L184-L220","documentation":"When a LockManager.request() call has an AbortSignal and the request is queued (the lock is held elsewhere), aborting the signal rejects the request's promise. If the application set signal.reason it is re-thrown as-is; otherwise Deno throws a DOMException named AbortError with this message from ext/web/locks.js. The listener is removed and no lock is held — the callback never runs.","triggerScenarios":"Aborting an AbortController while request() is queued behind another holder; a timeout via setTimeout(() => ctrl.abort(), 5000) racing lock acquisition; server shutdown aborting in-flight lock requests.","commonSituations":"Adding request timeouts to lock acquisition so slow holders cannot stall workers; graceful-shutdown paths that abort pending requests; racing a lock against user cancellation in a web UI.","solutions":["Catch the rejection around the request() call and treat AbortError as 'did not acquire' — skip or retry the work.","Distinguish causes: if you set controller.abort(reason), compare e === reason before falling back to DOMException handling.","For timeouts, prefer AbortSignal.timeout(ms) and catch AbortError explicitly.","If aborts are unexpected, investigate the long lock holder — that is the real cause, not the abort."],"exampleFix":"// before\nconst p = navigator.locks.request(\"r\", { signal: ctrl.signal }, cb);\nawait p; // unhandled AbortError when aborted\n\n// after\ntry {\n  await navigator.locks.request(\"r\", { signal: ctrl.signal }, cb);\n} catch (e) {\n  if (e.name === \"AbortError\") return; // acquisition cancelled\n  throw e;\n}","handlingStrategy":"try-catch","validationCode":"if (opts.signal?.aborted) {\n  return; // nothing to request\n}\nawait navigator.locks.request(n, opts, cb);","typeGuard":"function isAbortError(e) {\n  return e instanceof DOMException && e.name === \"AbortError\";\n}","tryCatchPattern":"try {\n  await navigator.locks.request(n, { signal: ctrl.signal }, cb);\n} catch (e) {\n  if (e === ctrl.signal.reason || (e instanceof DOMException && e.name === \"AbortError\")) return; // cancelled while queued\n  throw e;\n}","preventionTips":["Always await request() inside try/catch when a signal is attached.","Use AbortSignal.timeout(ms) for acquisition deadlines and handle AbortError explicitly.","Set controller.abort(reason) to distinguish intentional cancellation from generic aborts."],"tags":["web-locks","locks","abort-signal","async","domexception"],"backgroundTag":"operation-aborted","analyzedSha":"9ad36f7a2cce60488e6ec52283efb32efddaf93a","analyzedAt":"2026-08-20T13:07:44.778Z","contentChangedAt":"2026-08-20T13:07:44.778Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}