mirror of
https://github.com/openai/codex.git
synced 2026-05-24 13:04:29 +00:00
## Why #22580 made app-server startup fail when the local SQLite state database cannot be initialized. Embedded/local TUI startup still continued on the permissive path, which left the CLI inconsistent and could hide a real startup problem behind unrelated UI. This brings local TUI startup onto the same fail-closed behavior while keeping recovery humane for the two failure modes we are seeing in practice: damaged database files and startup stalls caused by another process holding the database write lock. ## What changed - Embedded TUI startup now uses `state_db::try_init(...)` and returns a typed `LocalStateDbStartupError` that preserves the affected database path plus the underlying failure detail. - CLI startup handles that failure before entering the interactive TUI: - lock-contention failures tell users to quit other Codex processes and try again - failures consistent with a broken local database offer a safe repair that backs up Codex-owned SQLite files, rebuilds local database files, and retries startup once - declined or unsuccessful repairs print concise guidance plus technical details - Shared startup error plumbing lives in `tui/src/startup_error.rs`, while CLI recovery policy and focused recovery tests live in `cli/src/state_db_recovery.rs`. ## Verification - `cargo test -p codex-tui embedded_state_db_failure_is_typed_for_cli_recovery` - `cargo test -p codex-cli state_db_recovery` - Manually held an exclusive SQLite lock on `state_5.sqlite` and confirmed the CLI shows lock-specific guidance without offering repair. - Manually exercised the repair path with a deliberately invalid `sqlite_home` and confirmed it backs up the blocking path and resumes startup.
30 lines
605 B
Rust
30 lines
605 B
Rust
use std::path::Path;
|
|
use std::path::PathBuf;
|
|
|
|
#[derive(Debug, thiserror::Error)]
|
|
#[error(
|
|
"failed to initialize sqlite state db at {}: {detail}",
|
|
state_db_path.display()
|
|
)]
|
|
pub struct LocalStateDbStartupError {
|
|
state_db_path: PathBuf,
|
|
detail: String,
|
|
}
|
|
|
|
impl LocalStateDbStartupError {
|
|
pub fn new(state_db_path: PathBuf, detail: String) -> Self {
|
|
Self {
|
|
state_db_path,
|
|
detail,
|
|
}
|
|
}
|
|
|
|
pub fn state_db_path(&self) -> &Path {
|
|
self.state_db_path.as_path()
|
|
}
|
|
|
|
pub fn detail(&self) -> &str {
|
|
self.detail.as_str()
|
|
}
|
|
}
|