fix(cli): handle missing database gracefully during classify#63
Conversation
Running classify in a directory with no review_classification.db produced a raw SQLAlchemy traceback (OperationalError: no such table: pullrequest) because the org path queries the DB before any table is created. - Add database_exists() helper and an upfront guard in the classify command that prints a clean error and exits 1 when no DB is present. - Harden get_repos_for_org() to return [] on OperationalError, mirroring get_latest_pr_date(), for present-but-uninitialized databases. Closes #62 Co-Authored-By: Claude Opus 4.8 <[email protected]>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 092167ed48
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| except OperationalError: | ||
| return [] |
There was a problem hiding this comment.
Report uninitialized org databases as errors
When a review_classification.db file exists but has no tables (for example, left behind by an earlier failed run), the new database_exists() guard passes and classify --org ... reaches this handler. Returning [] for the missing pullrequest table makes _resolve_targets produce no repos, so _print_detect_results sees no failures and the command exits successfully with an empty report instead of telling the user to run fetch first.
Useful? React with 👍 / 👎.
An empty review_classification.db left behind by a failed run passed the file-only existence check, so classify --org returned [] from get_repos_for_org and exited 0 with an empty report instead of prompting the user to run fetch. Replace database_exists() with database_is_initialized(), which keeps the on-disk short-circuit (no stray file creation) and additionally verifies the pullrequest table exists via the SQLAlchemy inspector. Co-Authored-By: Claude Opus 4.8 <[email protected]>
Summary
Running
review-classify classifyfrom a directory wherereview_classification.dbdoes not yet exist produced a multi-screen SQLAlchemy traceback ending inOperationalError: (sqlite3.OperationalError) no such table: pullrequest.The
--orgpath resolves org → repos by querying the database (get_repos_for_org) before any table is created, so SQLAlchemy lazily created an empty DB file and the query crashed. This PR replaces that traceback with a clean, actionable error message for both the--repoand--orgpaths.Closes #62
Changes
CLI
classifycommand — if no database exists, printError: No database found. Run 'review-classify fetch' first to collect PR data.and exit with code 1, before any DB work (avoids creating a stray empty DB file).Database
database_exists()helper (checks for the SQLite file on disk). Hardenedget_repos_for_org()to return[]onOperationalErrorinstead of raising, mirroring the existingget_latest_pr_date()pattern — covers present-but-uninitialized databases.Tests
--repoand--orgpaths exit 1 with the clean message, leak noOperationalError/traceback text, and create no stray DB file.database_exists()(file presence) andget_repos_for_org()returning[]when the table is missing.Testing
uv run ruff check) ✅uv run ruff format) ✅uv run mypy src tests) ✅uv run pytest -m "not integration") — 80 passed ✅Usage Examples
🤖 Generated with Claude Code