| Crates.io | oxiderr |
| lib.rs | oxiderr |
| version | 0.1.0 |
| created_at | 2025-01-31 19:10:45.480396+00 |
| updated_at | 2025-01-31 19:10:45.480396+00 |
| description | Streamlining Error Handling in Rust |
| homepage | https://github.com/cdumay/oxiderr |
| repository | https://github.com/cdumay/oxiderr |
| max_upload_size | |
| id | 1537749 |
| size | 29,100 |
oxiderr is a Rust library designed for extended error management. It leverages the oxiderr-derive crate, which provides procedural macros
to simplify the definition of structured error types. The primary goal of oxiderr is to enhance error handling in Rust applications by
making error definition more declarative and reducing boilerplate code.
oxiderr::AsError trait for easy integration.To utilize oxiderr in your project, follow these steps:
oxiderr with the feature derive in your Cargo.toml:[dependencies]
oxiderr = "0.1"
oxiderr::ErrorKind and struct which implement oxiderr::AsError to handle an error:#[allow(non_upper_case_globals)]
pub const IoError: oxiderr::ErrorKind = oxiderr::ErrorKind(
"IoError",
"Input / output error",
500,
"The requested file raised error"
);
#[derive(Debug, Clone)]
pub struct NotFoundError {
class: String,
message: String,
details: Option<std::collections::BTreeMap<String, serde_value::Value>>,
}
impl NotFoundError {
pub const kind: oxiderr::ErrorKind = IoError;
pub fn new() -> Self {
Self {
class: format!("{}::{}::{}", Self::kind.side(), Self::kind.name(), "NotFoundError"),
message: Self::kind.description().into(),
details: None,
}
}
pub fn set_message(mut self, message: String) -> Self {
self.message = message;
self
}
pub fn set_details(mut self, details: std::collections::BTreeMap<String, serde_value::Value>) -> Self {
self.details = Some(details);
self
}
pub fn convert(error: oxiderr::Error) -> Self {
let mut err_clone = error.clone();
let mut details = error.details.unwrap_or_default();
err_clone.details = None;
details.insert("origin".to_string(), serde_value::to_value(err_clone).unwrap());
Self {
class: format!("{}::{}::{}", Self::kind.side(), Self::kind.name(), "NotFoundError"),
message: Self::kind.description().into(),
details: Some(details),
}
}
}
impl oxiderr::AsError for NotFoundError {
fn kind() -> oxiderr::ErrorKind {
Self::kind
}
fn class(&self) -> String {
self.class.clone()
}
fn message(&self) -> String {
self.message.clone()
}
fn details(&self) -> Option<std::collections::BTreeMap<String, serde_value::Value>> {
self.details.clone()
}
}
impl std::error::Error for NotFoundError {}
impl std::fmt::Display for NotFoundError {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(f, "[{}] {} ({}): {}", Self::kind.message_id(), "NotFoundError", Self::kind.code(), self.message())
}
}
In this example:
IoError as oxiderr::ErrorKindNotFoundError which implements oxiderr::AsErroruse std::fs::File;
use std::io::Read;
fn try_open_file(path: &str) -> oxiderr::Result<File> {
Ok(File::open(path).map_err(|err| NotFoundError::new().set_message(err.to_string()))?)
}
fn main() {
let path = "example.txt";
match try_open_file(path) {
Ok(file) => println!("File: {:?}", file),
Err(e) => eprintln!("{}", e),
}
}
This will output:
[Err-00001] Client::IoError::NotFoundError (500) - No such file or directory (os error 2)
To automatically generate implementations for custom error types, enable the feature derive in your Cargo.toml:
[dependencies]
oxiderr = { version = "0.1", features = ["derive"] }
Then, use the provided derive macros to define your error and error kind structs:
use oxiderr::{define_errors, define_kinds, AsError};
define_kinds! {
UnknownError = ("Err-00001", 500, "Unexpected error"),
IoError = ("Err-00001", 400, "IO error")
}
define_errors! {
Unexpected = UnknownError,
FileRead = IoError,
FileNotExists = IoError
}
See oxiderr-derive documentation for more information.