{"record":{"id":"160a54f13caa6225","repo":"different-ai/openwork","slug":"abort-err","errorCode":"ABORT_ERR","errorMessage":"File read aborted","messagePattern":"File read aborted","errorType":"error_code","errorClass":"Error","httpStatus":null,"severity":"info","filePath":"apps/server/src/jsonc.ts","lineNumber":41,"sourceCode":"\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n  return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction hasErrorCode(error: unknown, code: string): boolean {\n  return isRecord(error) && error.code === code;\n}\n\nfunction fileReadError(code: string, message: string): Error {\n  const error = new Error(message);\n  Object.defineProperty(error, \"code\", { value: code, enumerable: true });\n  return error;\n}\n\nfunction throwIfAborted(signal: AbortSignal | undefined): void {\n  if (!signal?.aborted) return;\n  if (signal.reason instanceof Error) throw signal.reason;\n  throw fileReadError(\"ABORT_ERR\", \"File read aborted\");\n}\n\n/**\n * Read a small diagnostics input without following symlinks or opening a FIFO\n * in blocking mode. The size is checked both before and while reading so a\n * file that grows after inspection cannot exceed the caller's memory budget.\n */\nexport async function readBoundedRegularTextFile(\n  path: string,\n  options: { maxBytes: number; signal?: AbortSignal },\n): Promise<string> {\n  if (!Number.isSafeInteger(options.maxBytes) || options.maxBytes < 0) {\n    throw new RangeError(\"maxBytes must be a non-negative safe integer\");\n  }\n  throwIfAborted(options.signal);\n  const pathMetadata = await lstat(path);\n  throwIfAborted(options.signal);\n  if (!pathMetadata.isFile()) {","sourceCodeStart":23,"sourceCodeEnd":59,"githubUrl":"https://github.com/different-ai/openwork/blob/2b7df46e8ae1517d64c896c7793d2d52ec845669/apps/server/src/jsonc.ts#L23-L59","documentation":"throwIfAborted in jsonc.ts converts an already-aborted AbortSignal into a thrown error: if the signal's reason is an Error it is rethrown as-is, otherwise a generic Error with code ABORT_ERR and message \"File read aborted\" is thrown. Bounded file reads call it at every checkpoint so a cancelled read stops promptly.","triggerScenarios":"Passing an AbortSignal to readBoundedRegularTextFile/readJsoncFile that is already aborted, or aborting it mid-read (request timeout, caller cancellation) at one of the throwIfAborted checkpoints before, between, or during chunk reads.","commonSituations":"HTTP handlers whose request is cancelled while reading a diagnostics JSONC file; AbortSignal.timeout firing during a slow disk read; callers cancelling scans before the file read completes.","solutions":["Check signal.aborted before initiating the read and skip the call if already cancelled.","Size the AbortController timeout generously enough for the read to finish.","Catch ABORT_ERR (or the signal's own reason) and treat it as normal cancellation, not a file failure.","Reuse a single controller per logical operation so aborts are intentional and observable."],"exampleFix":"// before\nconst text = await readJsoncFile(path, { signal: controller.signal }); // throws ABORT_ERR when cancelled\n// after\nif (controller.signal.aborted) return null;\ntry {\n  return await readJsoncFile(path, { signal: controller.signal });\n} catch (e) {\n  if ((e as NodeJS.ErrnoException).code === \"ABORT_ERR\") return null;\n  throw e;\n}","handlingStrategy":"try-catch","validationCode":"if (signal?.aborted) return null; // skip the read entirely","typeGuard":"null","tryCatchPattern":"try {\n  return await readJsoncFile(path, { signal });\n} catch (e) {\n  if ((e as NodeJS.ErrnoException).code === \"ABORT_ERR\" || (e as Error)?.name === \"AbortError\") return null;\n  throw e;\n}","preventionTips":["Check signal.aborted before each expensive call.","Size AbortSignal.timeout budgets above worst-case disk latency.","Distinguish cancellation from file errors in catch blocks.","Reuse one AbortController per logical operation."],"tags":["abort","cancellation","filesystem","abortsignal"],"backgroundTag":"operation-aborted","analyzedSha":"2b7df46e8ae1517d64c896c7793d2d52ec845669","analyzedAt":"2026-09-01T07:59:23.713Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}