From 8270b641a40072b4a7447e957d814adc38d6516c Mon Sep 17 00:00:00 2001 From: Rainier Potgieter Date: Wed, 27 May 2026 00:28:59 +0200 Subject: [PATCH] fix(fixtures): fail loud on non-ENOENT readdir errors in the conformance runner The bare catch around readdirSync treated every error as "directory not found", silently skipped the whole category, and continued to exit 0. A filesystem hiccup, permission error, or transient I/O fault on valid/, invalid/, or edge-cases/ would report partial success as full success. Narrow the catch: on err.code === "ENOENT" keep the quiet skip and return; on any other code (EACCES, ENOTDIR, EIO, EMFILE, ...) write a loud message to stderr and process.exit(2). The exit code is distinct from the existing exit 1 for test failures and exit 0 for all-pass, so CI can tell "runner could not run" apart from "tests failed". No automated exit-2 test is committed: the runner is a self-executing script with hardcoded categories that calls process.exit at the top level, so asserting the exit code would require refactoring it into an importable module plus a subprocess harness in a separate file, beyond this single-file fix. The non-ENOENT path was verified manually against the real runner code (pointing a category at a file yields "Failed to read .../: ENOTDIR ..." and exit 2), and the normal run still exits 0 across all three categories. Co-Authored-By: Claude Opus 4.7 (1M context) --- spec/fixtures/run-fixtures.mjs | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/spec/fixtures/run-fixtures.mjs b/spec/fixtures/run-fixtures.mjs index aff0310..a12cf30 100644 --- a/spec/fixtures/run-fixtures.mjs +++ b/spec/fixtures/run-fixtures.mjs @@ -98,9 +98,16 @@ function runCategory(category) { files = readdirSync(dir) .filter((f) => f.endsWith(".logic.md")) .sort(); - } catch { - console.log(`\n⚠ Skipping ${category}/ (directory not found)`); - return; + } catch (err) { + if (err.code === "ENOENT") { + console.log(`\n⚠ Skipping ${category}/ (directory not found)`); + return; + } + // Any other error (EACCES, ENOTDIR, EIO, EMFILE, ...) means the runner + // could not read a category it was meant to read. Fail loud with a + // distinct exit code so partial success is never reported as full success. + console.error(`\n✗ Failed to read ${category}/: ${err.message}`); + process.exit(2); } console.log(`\n${category}/`);