Skip to content

fix(cli): handle missing database gracefully during classify#63

Merged
ghinks merged 2 commits into
mainfrom
fix/classify-missing-db-graceful-error
Jun 15, 2026
Merged

fix(cli): handle missing database gracefully during classify#63
ghinks merged 2 commits into
mainfrom
fix/classify-missing-db-graceful-error

Conversation

@ghinks

@ghinks ghinks commented Jun 15, 2026

Copy link
Copy Markdown
Owner

Summary

Running review-classify classify from a directory where review_classification.db does not yet exist produced a multi-screen SQLAlchemy traceback ending in OperationalError: (sqlite3.OperationalError) no such table: pullrequest.

The --org path 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 --repo and --org paths.

Closes #62

Changes

CLI

  • cli/app.py: Added an upfront guard in the classify command — if no database exists, print Error: 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

  • sqlite/database.py: Added database_exists() helper (checks for the SQLite file on disk). Hardened get_repos_for_org() to return [] on OperationalError instead of raising, mirroring the existing get_latest_pr_date() pattern — covers present-but-uninitialized databases.

Tests

  • tests/cli/test_classify.py (new): Asserts the --repo and --org paths exit 1 with the clean message, leak no OperationalError/traceback text, and create no stray DB file.
  • tests/sqlite/test_database.py: Added coverage for database_exists() (file presence) and get_repos_for_org() returning [] when the table is missing.

Testing

  • Linting checks passed (uv run ruff check) ✅
  • Formatting checks passed (uv run ruff format) ✅
  • Strict type checks passed (uv run mypy src tests) ✅
  • Unit tests passed (uv run pytest -m "not integration") — 80 passed ✅

Usage Examples

# In a directory with no fetched data:
$ review-classify classify --org expressjs
Error: No database found. Run 'review-classify fetch' first to collect PR data.
# exit code: 1, no traceback, no stray review_classification.db created

🤖 Generated with Claude Code

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]>

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 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".

Comment on lines +144 to +145
except OperationalError:
return []

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge 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 👍 / 👎.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

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]>
@ghinks ghinks merged commit 34dfd2d into main Jun 15, 2026
1 check passed
@ghinks ghinks deleted the fix/classify-missing-db-graceful-error branch June 15, 2026 12:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

during the classify handle db read failure gracefully

1 participant