Merge pull request 'feat: implement custom error handling with AppError enum and update dependencies' (#4) from feature/error-handling into master
Reviewed-on: finwise/finewise#4
This commit was merged in pull request #4.
This commit is contained in:
2
Cargo.lock
generated
2
Cargo.lock
generated
@@ -1276,7 +1276,7 @@ dependencies = [
|
||||
"tauri",
|
||||
"tauri-build",
|
||||
"tauri-plugin-opener",
|
||||
"thiserror 1.0.69",
|
||||
"thiserror 2.0.18",
|
||||
"uuid",
|
||||
]
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ serde_json = { workspace = true }
|
||||
sea-orm = { workspace = true }
|
||||
chrono = { workspace = true }
|
||||
migration = { path = "../crates/migration" }
|
||||
thiserror = "1"
|
||||
thiserror = "2"
|
||||
rust_decimal = "1"
|
||||
uuid = { version = "1", features = ["v4"] }
|
||||
|
||||
|
||||
84
src-tauri/src/errors/app_error.rs
Normal file
84
src-tauri/src/errors/app_error.rs
Normal file
@@ -0,0 +1,84 @@
|
||||
use thiserror::Error;
|
||||
|
||||
#[derive(Error, Debug)]
|
||||
pub enum AppError {
|
||||
#[error("Database error: {0}")]
|
||||
Database(#[from] sea_orm::DbErr),
|
||||
|
||||
#[error("Validation error: {0}")]
|
||||
Validation(String),
|
||||
|
||||
#[error("Not found: {0}")]
|
||||
NotFound(String),
|
||||
|
||||
#[error("Invalid amount: {0}")]
|
||||
InvalidAmount(String),
|
||||
|
||||
#[error("Currency mismatch: expected {expected}, got {actual}")]
|
||||
CurrencyMismatch { expected: String, actual: String },
|
||||
|
||||
#[error("IO error: {0}")]
|
||||
Io(#[from] std::io::Error),
|
||||
|
||||
#[error("Serialization error: {0}")]
|
||||
Serialization(#[from] serde_json::Error),
|
||||
|
||||
#[error("Internal error: {0}")]
|
||||
Internal(String),
|
||||
|
||||
#[error("{0}")]
|
||||
Other(String),
|
||||
}
|
||||
|
||||
#[derive(serde::Serialize)]
|
||||
#[serde(tag = "kind", content = "message")]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
enum ErrorKind {
|
||||
Database(String),
|
||||
Validation(String),
|
||||
NotFound(String),
|
||||
InvalidAmount(String),
|
||||
CurrencyMismatch { expected: String, actual: String },
|
||||
Io(String),
|
||||
Serialization(String),
|
||||
Internal(String),
|
||||
Other(String),
|
||||
}
|
||||
|
||||
impl serde::Serialize for AppError {
|
||||
fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
|
||||
where
|
||||
S: serde::ser::Serializer,
|
||||
{
|
||||
let error_message = self.to_string();
|
||||
let error_kind: ErrorKind = match self {
|
||||
Self::Io(_) => ErrorKind::Io(error_message),
|
||||
Self::Database(_) => ErrorKind::Database(error_message),
|
||||
Self::Validation(_) => ErrorKind::Validation(error_message),
|
||||
Self::NotFound(_) => ErrorKind::NotFound(error_message),
|
||||
Self::InvalidAmount(_) => ErrorKind::InvalidAmount(error_message),
|
||||
Self::CurrencyMismatch { expected, actual } => ErrorKind::CurrencyMismatch {
|
||||
expected: expected.clone(),
|
||||
actual: actual.clone(),
|
||||
},
|
||||
Self::Serialization(_) => ErrorKind::Serialization(error_message),
|
||||
Self::Internal(_) => ErrorKind::Internal(error_message),
|
||||
Self::Other(_) => ErrorKind::Other(error_message),
|
||||
};
|
||||
error_kind.serialize(serializer)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<AppError> for String {
|
||||
fn from(error: AppError) -> Self {
|
||||
error.to_string()
|
||||
}
|
||||
}
|
||||
|
||||
impl From<rust_decimal::Error> for AppError {
|
||||
fn from(error: rust_decimal::Error) -> Self {
|
||||
AppError::InvalidAmount(error.to_string())
|
||||
}
|
||||
}
|
||||
|
||||
pub type CommandResult<T> = std::result::Result<T, AppError>;
|
||||
1
src-tauri/src/errors/mod.rs
Normal file
1
src-tauri/src/errors/mod.rs
Normal file
@@ -0,0 +1 @@
|
||||
pub mod app_error;
|
||||
@@ -1,4 +1,5 @@
|
||||
mod db;
|
||||
mod errors;
|
||||
|
||||
// Learn more about Tauri commands at https://tauri.app/develop/calling-rust/
|
||||
#[tauri::command]
|
||||
|
||||
Reference in New Issue
Block a user