From cdd981fe642208b89e03fe0e8881f00bb2f71d98 Mon Sep 17 00:00:00 2001 From: Cameron Cordes Date: Wed, 27 May 2026 22:30:19 -0400 Subject: [PATCH] fix: inline DB error source into DbError struct The previous fix logged the underlying error in a separate log line, but the error that propagated up still showed just "DbError { kind: InsertError }" at the call site. Now the source message is captured on the struct itself, so Debug/Display output at any call site shows the actual Diesel error inline. Co-Authored-By: Claude Opus 4.7 (1M context) --- src/database/mod.rs | 35 +++++++++++++++++++++++++++++++---- src/testhelpers.rs | 1 + 2 files changed, 32 insertions(+), 4 deletions(-) diff --git a/src/database/mod.rs b/src/database/mod.rs index ac2e5d3..d063bd0 100644 --- a/src/database/mod.rs +++ b/src/database/mod.rs @@ -193,19 +193,26 @@ pub fn connect() -> SqliteConnection { conn } -#[derive(Debug)] pub struct DbError { pub kind: DbErrorKind, + pub source: Option, } impl DbError { fn new(kind: DbErrorKind) -> Self { - DbError { kind } + DbError { kind, source: None } } + /// Capture the source error message AND log it. Callers should use + /// this from `map_err` closures so the underlying Diesel/SQLite + /// error survives the conversion to `DbError`. fn log(kind: DbErrorKind, source: impl std::fmt::Display) -> Self { - log::error!("DB {:?}: {}", kind, source); - DbError { kind } + let msg = source.to_string(); + log::error!("DB {:?}: {}", kind, msg); + DbError { + kind, + source: Some(msg), + } } fn exists() -> Self { @@ -213,6 +220,26 @@ impl DbError { } } +impl std::fmt::Debug for DbError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match &self.source { + Some(s) => write!(f, "DbError {{ kind: {:?}, source: {} }}", self.kind, s), + None => write!(f, "DbError {{ kind: {:?} }}", self.kind), + } + } +} + +impl std::fmt::Display for DbError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match &self.source { + Some(s) => write!(f, "{:?}: {}", self.kind, s), + None => write!(f, "{:?}", self.kind), + } + } +} + +impl std::error::Error for DbError {} + #[derive(Debug, PartialEq)] pub enum DbErrorKind { AlreadyExists, diff --git a/src/testhelpers.rs b/src/testhelpers.rs index 1536dbb..8c686a1 100644 --- a/src/testhelpers.rs +++ b/src/testhelpers.rs @@ -144,6 +144,7 @@ impl PreviewDao for TestPreviewDao { } else { Err(DbError { kind: DbErrorKind::UpdateError, + source: None, }) } }