{"id":13822837,"url":"https://github.com/lovasoa/custom_error","last_synced_at":"2025-06-21T05:01:57.851Z","repository":{"id":52974035,"uuid":"155780049","full_name":"lovasoa/custom_error","owner":"lovasoa","description":"Define custom errors without boilerplate using the custom_error! macro.","archived":false,"fork":false,"pushed_at":"2021-04-11T19:24:04.000Z","size":66,"stargazers_count":74,"open_issues_count":7,"forks_count":5,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-06-02T18:09:13.963Z","etag":null,"topics":["error-handling","rust"],"latest_commit_sha":null,"homepage":"https://crates.io/crates/custom_error","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-2-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/lovasoa.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2018-11-01T21:49:13.000Z","updated_at":"2025-02-17T02:56:18.000Z","dependencies_parsed_at":"2022-09-04T07:21:54.957Z","dependency_job_id":null,"html_url":"https://github.com/lovasoa/custom_error","commit_stats":null,"previous_names":[],"tags_count":7,"template":false,"template_full_name":null,"purl":"pkg:github/lovasoa/custom_error","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lovasoa%2Fcustom_error","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lovasoa%2Fcustom_error/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lovasoa%2Fcustom_error/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lovasoa%2Fcustom_error/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/lovasoa","download_url":"https://codeload.github.com/lovasoa/custom_error/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lovasoa%2Fcustom_error/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":261065242,"owners_count":23104761,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["error-handling","rust"],"created_at":"2024-08-04T08:02:20.192Z","updated_at":"2025-06-21T05:01:52.819Z","avatar_url":"https://github.com/lovasoa.png","language":"Rust","funding_links":[],"categories":["Rust"],"sub_categories":[],"readme":"# Rust custom error\n\n[![Rust](https://github.com/lovasoa/custom_error/actions/workflows/rust.yml/badge.svg)](https://github.com/lovasoa/custom_error/actions/workflows/rust.yml)\n[![Crates.io](https://img.shields.io/crates/v/custom_error)](https://crates.io/crates/custom_error)\n[![docs.rs](https://img.shields.io/docsrs/custom_error)](https://docs.rs/custom_error)\n\nThis crate contains a macro that should make it easier\nto define custom errors without having to write a lot of boilerplate code.\n\nThe `custom_error!` macro included in this crate takes a type name\nand a list of possible errors and generates a rust enumeration for all the cases,\ntogether with the required `impl` blocks implementing `std::error::Error`\nand `std::fmt::Display`. \n\nIf you only have a single case for an error you can also generate a struct\ninstead of an enum.\n\nYou can now write:\n\n```rust\nextern crate custom_error;\nuse custom_error::custom_error;\n\n// Note the use of braces rather than parentheses.\ncustom_error!{MyError\n    Unknown{code:u8} = \"unknown error with code {code}.\",\n    Err41            = \"Sit by a lake\"\n}\n```\n\ninstead of\n\n```rust\n#[derive(Debug)]\nenum MyError {\n    Unknown { code: u8 },\n    Err41,\n}\n\nimpl std::error::Error for MyError {}\n\nimpl std::fmt::Display for MyError {\n    fn fmt(\u0026self, f: \u0026mut std::fmt::Formatter)\n    -\u003e std::fmt::Result {\n        match self {\n            MyError::Unknown { code } =\u003e write!(f, \"unknown error with code {}.\" , code),\n            MyError::Err41 =\u003e write!(f, \"Sit by a lake\")\n        }\n    }\n}\n```\n\nIf you only have a single error case you can also generate a struct:\n```rust\nextern crate custom_error;\nuse custom_error::custom_error;\n\ncustom_error!{MyError{code:u8} = \"error with code {code}.\"}\n```\n\n## Simple error\n\nTo define a simple error, you only have to indicate three things:\n * the name of your custom error type,\n * the name of the different error cases,\n * a human-readable description for each case.\n\n```rust\nextern crate custom_error;\nuse custom_error::custom_error;\n\ncustom_error!{MyError\n    Bad      = \"Something bad happened\",\n    Terrible = \"This is a very serious error!!!\"\n}\n```\n\n## Custom error with parameters\n\nYou can store data inside your errors.\nIn order to do so, indicate the name and types of the fields to want to store in curly braces\nafter an error type.\n\n```rust\nextern crate custom_error;\nuse custom_error::custom_error;\n\ncustom_error!{SantaError\n    BadChild{name:String, foolishness:u8} = \"{name} has been bad {foolishness} times this year\",\n    TooFar                                = \"The location you indicated is too far from the north pole\",\n    InvalidReindeer{legs:u8}              = \"The reindeer has {legs} legs\"\n}\n\nassert_eq!(\n    \"Thomas has been bad 108 times this year\",\n    SantaError::BadChild{name: \"Thomas\".into(), foolishness: 108}.to_string());\n```\n\nThe error messages can reference your parameters using braces (`{parameter_name}`).\nIf you need some custom logic to display your parameters, you can use\n[advanced custom error messages](#advanced-custom-error-messages).\n\n## Wrapping other error types\n\nIf the cause of your error is another lower-level error, you can indicate that\nby adding a special `source` field to one of your error cases.\n\nThus, you can make your custom error wrap other error types,\nand the conversion from these foreign error types will be implemented automatically.\n\n```rust\n#[macro_use] extern crate custom_error;\nuse std::{io, io::Read, fs::File, result::Result, num::ParseIntError};\n\ncustom_error! {FileParseError\n    Io{source: io::Error}         = \"unable to read from the file\",\n    Format{source: ParseIntError} = \"the file does not contain a valid integer\",\n    TooLarge{value:u8}            = \"the number in the file ({value}) is too large\"\n}\n\nfn parse_hex_file(filename: \u0026str) -\u003e Result\u003cu8, FileParseError\u003e {\n    let mut contents = String::new();\n    // The '?' notation can convert from generic errors to our custom error type\n    File::open(filename)?.read_to_string(\u0026mut contents)?;\n    let value = u8::from_str_radix(\u0026contents, 16)?;\n    if value \u003e 42 {\n        Err(FileParseError::TooLarge { value })\n    } else {\n        Ok(value)\n    }\n}\n\nfn main() {\n    let parse_result = parse_hex_file(\"/i'm not a file/\");\n    assert_eq!(\"unable to read from the file\", parse_result.unwrap_err().to_string());\n}\n```\n\n## Visibility\n\nYou can make an error type public by adding the `pub` keyword\nat the beginning of the declaration.\n\n```rust\ncustom_error!{pub MyError A=\"error a\", B=\"error b\"}\n```\n\n## Attributes\n\nYou can derive traits for your error types by adding attributes\nto the beginning of your macro invocation.\n\n```rust\ncustom_error!{#[derive(PartialEq,PartialOrd)] MyError A=\"error a\", B=\"error b\"}\nassert!(MyError::A \u003c MyError::B);\n```\n\nSince [doc comments](https://doc.rust-lang.org/beta/rustdoc/print.html#the-doc-attribute)\nare just syntax sugar for `#[doc = \"...\"]`, you can use them too:\n \n ```rust\ncustom_error!{\n    /// This is the documentation for my error type\n    pub MyError A=\"error a\", B=\"error b\"\n}\n```\n\n## Advanced custom error messages\n\nIf you want to use error messages that you cannot express with\nsimple formatting strings, you can generate your error messages with\ncustom code.\n\nIn the following example, we use this feature to display a\ndifferent error message based on the cause of the underlying IO error.\n\n```rust\ncustom_error!{ pub MyError\n    Io{source: Error} = @{\n        match source.kind() {\n            NotFound =\u003e \"The file does not exist\",\n            TimedOut =\u003e \"The operation timed out\",\n            _ =\u003e \"unknown error\",\n        }\n    },\n    Unknown = \"unknown error\"\n}\n```\n\n## nostd\n\nThis crate supports [`no-std`](https://docs.rust-embedded.org/book/intro/no-std.html): it can be built without the rust standard library.\nTo use the no-std version, disable the std feature in this crate in your `Cargo.toml` : \n\n```toml\n[dependencies]\ncustom_error = { version = \"1\", default-features = false } # nostd compatible\n```\n\n### unstable\n\nThere is also an `unstable` feature \nthat implements the nostd error trait on `AllocError` and `TryReserveError` in no-std.\n\n## Minimum supported rust version\n\nThis crate works and is tested with rust \u003e= [1.36](https://github.com/rust-lang/rust/blob/master/RELEASES.md#version-1360-2019-07-04)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flovasoa%2Fcustom_error","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flovasoa%2Fcustom_error","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flovasoa%2Fcustom_error/lists"}