All Projects → lovasoa → custom_error

lovasoa / custom_error

Licence: BSD-2-Clause license
Define custom errors without boilerplate using the custom_error! macro.

Programming Languages

rust
11053 projects

Projects that are alternatives of or similar to custom error

ngx-errors
Angular directives for displaying validation errors
Stars: ✭ 51 (-27.14%)
Mutual labels:  error-handling
koa-better-error-handler
A better error-handler for Lad and Koa. Makes `ctx.throw` awesome (best used with koa-404-handler)
Stars: ✭ 51 (-27.14%)
Mutual labels:  error-handling
optionals
Rust-like error handling and options for TypeScript and Deno!
Stars: ✭ 97 (+38.57%)
Mutual labels:  error-handling
pony-cause
Ponyfill and helpers for the standardized Error Causes
Stars: ✭ 42 (-40%)
Mutual labels:  error-handling
co demo
A step-by-step guide about how to avoid callback hell with ES6 Promises + generators (aka make your own "co")
Stars: ✭ 17 (-75.71%)
Mutual labels:  error-handling
express-error-slack
Express error handling middleware for reporting error to Slack
Stars: ✭ 14 (-80%)
Mutual labels:  error-handling
go-errors
⚠️ Better GoLang error handling.
Stars: ✭ 18 (-74.29%)
Mutual labels:  error-handling
of
🍬 Promise wrapper with sugar 🍬
Stars: ✭ 13 (-81.43%)
Mutual labels:  error-handling
auto-async-wrap
automatic async middleware wrapper for expressjs errorhandler.
Stars: ✭ 21 (-70%)
Mutual labels:  error-handling
fortran-error-handler
Comprehensive error framework for applications requiring functional and robust error handling, utilising the power of modern object-oriented Fortran.
Stars: ✭ 19 (-72.86%)
Mutual labels:  error-handling
TrackJS-Node
TrackJS Error Monitoring agent for NodeJS
Stars: ✭ 26 (-62.86%)
Mutual labels:  error-handling
SolveWithStack
Android library for helping you to reach out to best possible answer for your bug/error available on stack overflow and will show it in your Android Studio Console only.
Stars: ✭ 15 (-78.57%)
Mutual labels:  error-handling
go-errors
A super tiny package for error encapsulation in idiomatic Go
Stars: ✭ 14 (-80%)
Mutual labels:  error-handling
rakered
The open source components from rake.red
Stars: ✭ 28 (-60%)
Mutual labels:  error-handling
raygun4py
Python provider for Raygun
Stars: ✭ 18 (-74.29%)
Mutual labels:  error-handling
ignition-stackoverflow
An Ignition tab that fetches StackOverflow questions and provides a searchbar.
Stars: ✭ 74 (+5.71%)
Mutual labels:  error-handling
elmah.io
ELMAH error logger for sending errors to elmah.io.
Stars: ✭ 31 (-55.71%)
Mutual labels:  error-handling
kotlin-multiplatform-example
A Kotlin multiplatform example app that targets Android, ReactJS, iOS, JavaFx, and Spring Boot
Stars: ✭ 115 (+64.29%)
Mutual labels:  error-handling
nested-error-stacks
A node.js module for creating Error objects with nested Errors in stacktraces
Stars: ✭ 86 (+22.86%)
Mutual labels:  error-handling
raygun4android
Android crash reporting provider for Raygun
Stars: ✭ 19 (-72.86%)
Mutual labels:  error-handling

Rust custom error

Rust Crates.io docs.rs

This crate contains a macro that should make it easier to define custom errors without having to write a lot of boilerplate code.

The custom_error! macro included in this crate takes a type name and a list of possible errors and generates a rust enumeration for all the cases, together with the required impl blocks implementing std::error::Error and std::fmt::Display.

If you only have a single case for an error you can also generate a struct instead of an enum.

You can now write:

extern crate custom_error;
use custom_error::custom_error;

// Note the use of braces rather than parentheses.
custom_error!{MyError
    Unknown{code:u8} = "unknown error with code {code}.",
    Err41            = "Sit by a lake"
}

instead of

#[derive(Debug)]
enum MyError {
    Unknown { code: u8 },
    Err41,
}

impl std::error::Error for MyError {}

impl std::fmt::Display for MyError {
    fn fmt(&self, f: &mut std::fmt::Formatter)
    -> std::fmt::Result {
        match self {
            MyError::Unknown { code } => write!(f, "unknown error with code {}." , code),
            MyError::Err41 => write!(f, "Sit by a lake")
        }
    }
}

If you only have a single error case you can also generate a struct:

extern crate custom_error;
use custom_error::custom_error;

custom_error!{MyError{code:u8} = "error with code {code}."}

Simple error

To define a simple error, you only have to indicate three things:

  • the name of your custom error type,
  • the name of the different error cases,
  • a human-readable description for each case.
extern crate custom_error;
use custom_error::custom_error;

custom_error!{MyError
    Bad      = "Something bad happened",
    Terrible = "This is a very serious error!!!"
}

Custom error with parameters

You can store data inside your errors. In order to do so, indicate the name and types of the fields to want to store in curly braces after an error type.

extern crate custom_error;
use custom_error::custom_error;

custom_error!{SantaError
    BadChild{name:String, foolishness:u8} = "{name} has been bad {foolishness} times this year",
    TooFar                                = "The location you indicated is too far from the north pole",
    InvalidReindeer{legs:u8}              = "The reindeer has {legs} legs"
}

assert_eq!(
    "Thomas has been bad 108 times this year",
    SantaError::BadChild{name: "Thomas".into(), foolishness: 108}.to_string());

The error messages can reference your parameters using braces ({parameter_name}). If you need some custom logic to display your parameters, you can use advanced custom error messages.

Wrapping other error types

If the cause of your error is another lower-level error, you can indicate that by adding a special source field to one of your error cases.

Thus, you can make your custom error wrap other error types, and the conversion from these foreign error types will be implemented automatically.

#[macro_use] extern crate custom_error;
use std::{io, io::Read, fs::File, result::Result, num::ParseIntError};

custom_error! {FileParseError
    Io{source: io::Error}         = "unable to read from the file",
    Format{source: ParseIntError} = "the file does not contain a valid integer",
    TooLarge{value:u8}            = "the number in the file ({value}) is too large"
}

fn parse_hex_file(filename: &str) -> Result<u8, FileParseError> {
    let mut contents = String::new();
    // The '?' notation can convert from generic errors to our custom error type
    File::open(filename)?.read_to_string(&mut contents)?;
    let value = u8::from_str_radix(&contents, 16)?;
    if value > 42 {
        Err(FileParseError::TooLarge { value })
    } else {
        Ok(value)
    }
}

fn main() {
    let parse_result = parse_hex_file("/i'm not a file/");
    assert_eq!("unable to read from the file", parse_result.unwrap_err().to_string());
}

Visibility

You can make an error type public by adding the pub keyword at the beginning of the declaration.

custom_error!{pub MyError A="error a", B="error b"}

Attributes

You can derive traits for your error types by adding attributes to the beginning of your macro invocation.

custom_error!{#[derive(PartialEq,PartialOrd)] MyError A="error a", B="error b"}
assert!(MyError::A < MyError::B);

Since doc comments are just syntax sugar for #[doc = "..."], you can use them too:

custom_error!{
   /// This is the documentation for my error type
   pub MyError A="error a", B="error b"
}

Advanced custom error messages

If you want to use error messages that you cannot express with simple formatting strings, you can generate your error messages with custom code.

In the following example, we use this feature to display a different error message based on the cause of the underlying IO error.

custom_error!{ pub MyError
    Io{source: Error} = @{
        match source.kind() {
            NotFound => "The file does not exist",
            TimedOut => "The operation timed out",
            _ => "unknown error",
        }
    },
    Unknown = "unknown error"
}

nostd

This crate supports no-std: it can be built without the rust standard library. To use the no-std version, disable the std feature in this crate in your Cargo.toml :

[dependencies]
custom_error = { version = "1", default-features = false } # nostd compatible

unstable

There is also an unstable feature that implements the nostd error trait on AllocError and TryReserveError in no-std.

Minimum supported rust version

This crate works and is tested with rust >= 1.36

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].