Repository navigation
fix: say a token or database path that names a directory is one - #174
Conversation
…SDIR writeFileSync's EISDIR escaped login's catch as a plain Error, so the user got Node's message and no hint. writeToken now turns it into a BAD_ARGS CliError that names the path and suggests a file inside it. Closes #149 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018qh9xqviBHYmzVtmQWSKqA
…rmissions problem SQLite reports a directory as "unable to open database file", which the hint table maps to the permissions hint. openDatabase now checks for a directory before it opens and names it in the error. Closes #151 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018qh9xqviBHYmzVtmQWSKqA
|
Codex review ( Reviewed The touched tests passed: 31 tests across Simplification: not needed Verdict: Approve |
[Medium impact] The PR appears safe to merge, with two non-blocking findings from the previous review still open. FindingsSummaryThe PR gives clearer errors when a token or database path names a directory.
Reviews (2) · Last reviewed commit: "Merge remote-tracking branch 'origin/mai..." · Reviewed by Greptile |
| expect({ code: (err as CliError).code, message: (err as CliError).message, hint: (err as CliError).hint }).toEqual({ | ||
| code: 'DB_ERROR', | ||
| message: `Cannot open database ${target}: it is a directory.`, | ||
| hint: `Point --db / OURA_DB_PATH at a file, such as ${target}/oura.db.`, |
There was a problem hiding this comment.
Correct hints fail Windows tests
The new tests expect / before the example filename, but both functions build their hints with join, which uses backslashes on Windows. These exact checks fail even when the returned hint is correct. Use join(target, 'oura.db') here and join(dir, '.oura-token') in src/commands/login.test.ts.
|
|
||
| export function openDatabase(explicit?: string): Database { | ||
| const dbPath = getDbPath(explicit); | ||
| if (dbPath !== ':memory:' && existsSync(dbPath) && statSync(dbPath).isDirectory()) { |
There was a problem hiding this comment.
File checks bypass database errors
statSync now runs outside the error wrapper. If another process removes the database after existsSync succeeds—for example, while rebuilding the cache—statSync throws a raw file error. Commands then report UNKNOWN with exit code 1 instead of DB_ERROR with exit code 4, and doctor loses the hint. Keep file checks inside the wrapper while preserving the directory-specific CliError.
# Conflicts: # CHANGELOG.md
Closes #149, closes #151.
What
login --path <directory>(orOURA_TOKEN_PATHnaming one) isBAD_ARGS:<path> is a directory., with<path>/.oura-tokenas the example in the hint.writeTokencatchesEISDIRand rethrows every other error unchanged. (login --token x --path <existing directory>fails with a raw EISDIR and no hint #149)--dborOURA_DB_PATHnaming a directory isDB_ERROR:Cannot open database <path>: it is a directory., hintPoint --db / OURA_DB_PATH at a file, such as <path>/oura.db.openDatabasechecks before it opens, outside the try block, so the permissions hint no longer replaces it.doctorshows the same fix, because it passes the open error's hint through. (OURA_DB_PATHpointing at a directory gets the permissions hint instead of "this is a directory" #151)loginletting a rawEISDIRthrough is gone, since a test now covers it.Why
Both reproduced on main (0.9.1 sources):
login --token x --path <dir>printederror: EISDIR: illegal operation on a directory, open '<dir>', exit 1, no hint.OURA_DB_PATH=<dir> oura-cli db todaygaveunable to open database filewith the hint about write permissions on the file and its directory.How checked
src/commands/login.test.ts(writeToken into a temp dir) andsrc/db/open.test.ts(openDatabase on a temp dir). Each asserts code, message and hint exactly.login --token x --path <existing directory>fails with a raw EISDIR and no hint #149:if ((err as NodeJS.ErrnoException).code !== 'EISDIR') throw err;→throw err;inlogin.ts: 1 of 5 fails (the new test).OURA_DB_PATHpointing at a directory gets the permissions hint instead of "this is a directory" #151: the directory checkif (dbPath !== ':memory:' && existsSync(dbPath) && statSync(dbPath).isDirectory()) {→if (false) {inopen.ts: 1 of 26 fails (the new test).bun run check: typecheck, Biome, Knip clean; 713 tests pass.🤖 Generated with Claude Code
https://claude.ai/code/session_018qh9xqviBHYmzVtmQWSKqA