feat(wave1): App error type and Result alias [claudbg-i09w]

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
main
Elijah Voigt 2 months ago
parent 3b62deb617
commit 1a2f999636

@ -1,11 +1,12 @@
--- ---
# claudbg-i09w # claudbg-i09w
title: App error type and Result alias title: App error type and Result alias
status: todo status: completed
type: task type: task
priority: normal
created_at: 2026-03-27T19:38:56Z created_at: 2026-03-27T19:38:56Z
updated_at: 2026-03-27T19:38:56Z updated_at: 2026-03-28T04:15:59Z
parent: claudbg-h7xu parent: claudbg-h7xu
--- ---
Define a top-level AppError enum (IoError, ParseError, DbError, NotFound, etc.) and a Result<T> alias. Use thiserror or a similar crate. Created src/error.rs with AppError enum (Io, Parse, Db, NotFound, InvalidArg) and Result<T> alias using thiserror. All variants have doc comments. Six unit tests verify Display impl for each variant and From<io::Error> conversion. Updated src/lib.rs to declare pub mod error and src/main.rs to import claudbg::error::Result.

@ -0,0 +1,73 @@
//! Application-level error types for claudbg.
/// Application-level error type.
#[derive(Debug, thiserror::Error)]
pub enum AppError {
/// Wraps [`std::io::Error`] for filesystem and I/O failures.
#[error("I/O error: {0}")]
Io(#[from] std::io::Error),
/// A parsing failure with a descriptive message.
#[error("Parse error: {0}")]
Parse(String),
/// A database operation failure with a descriptive message.
#[error("Database error: {0}")]
Db(String),
/// The requested session or agent ID was not found.
#[error("Session not found: {0}")]
NotFound(String),
/// An invalid argument was supplied by the user.
#[error("Invalid argument: {0}")]
InvalidArg(String),
}
/// Convenience `Result` alias using [`AppError`].
pub type Result<T> = std::result::Result<T, AppError>;
#[cfg(test)]
mod tests {
use super::*;
use std::io;
/// `AppError::Io` displays the wrapped I/O error message.
#[test]
fn display_io() {
let err = AppError::Io(io::Error::new(io::ErrorKind::NotFound, "file missing"));
assert_eq!(err.to_string(), "I/O error: file missing");
}
/// `AppError::Parse` displays the message passed to the constructor.
#[test]
fn display_parse() {
let err = AppError::Parse("bad JSON".to_string());
assert_eq!(err.to_string(), "Parse error: bad JSON");
}
/// `AppError::Db` displays the message passed to the constructor.
#[test]
fn display_db() {
let err = AppError::Db("connection refused".to_string());
assert_eq!(err.to_string(), "Database error: connection refused");
}
/// `AppError::NotFound` displays the ID that was missing.
#[test]
fn display_not_found() {
let err = AppError::NotFound("abc12345".to_string());
assert_eq!(err.to_string(), "Session not found: abc12345");
}
/// `AppError::InvalidArg` displays the invalid argument description.
#[test]
fn display_invalid_arg() {
let err = AppError::InvalidArg("unknown token: foo".to_string());
assert_eq!(err.to_string(), "Invalid argument: unknown token: foo");
}
/// `AppError::Io` can be constructed via `From<io::Error>`.
#[test]
fn from_io_error() {
let io_err = io::Error::new(io::ErrorKind::PermissionDenied, "denied");
let app_err: AppError = io_err.into();
assert!(app_err.to_string().contains("denied"));
}
}

@ -3,7 +3,7 @@
// pub mod cli; // pub mod cli;
// pub mod commands; // pub mod commands;
// pub mod db; // pub mod db;
// pub mod error; pub mod error;
// pub mod models; // pub mod models;
// pub mod output; // pub mod output;
// pub mod util; // pub mod util;

@ -1,3 +1,8 @@
//! claudbg binary entry point.
use claudbg::error::Result;
fn main() { fn main() {
let _: Result<()> = Ok(());
println!("Hello, world!"); println!("Hello, world!");
} }

Loading…
Cancel
Save