### Install mdbook using Cargo Source: https://github.com/nrc/error-docs/blob/main/README.md Install mdbook, the tool used for building the documentation, via the Rust package manager Cargo. ```bash cargo install mdbook ``` -------------------------------- ### Rust Try Block Example Source: https://github.com/nrc/error-docs/blob/main/rust-errors/result-and-error.md Demonstrates the use of a try block with the `?` operator to handle potential errors from multiple `parse` operations. Execution short-circuits on the first error encountered within the block. ```rust #![feature(try_blocks)] let result: Result = try { "1".parse::()? + "foo".parse::()? + "3".parse::()? }; ``` -------------------------------- ### Example of Cyclic Error Type Definitions Source: https://github.com/nrc/error-docs/blob/main/error-design/error-type-design.md Illustrates a potential infinite recursion issue when defining error types that can contain instances of each other. This pattern can complicate error recovery. ```rust pub enum A { // ... B(Box), } pub enum B { Foo, A(A), Other(Box), // ... } ``` -------------------------------- ### Basic Enum Error with Variant Data Source: https://github.com/nrc/error-docs/blob/main/error-design/error-type-design.md Defines a basic enum for error types where each variant holds specific associated data. This is a foundational example of the enum-style error design. ```rust pub enum MyError { Network(IoError, Request), Malformed(MalformedRespError), MissingHeader(String), UnknownField(String), } pub struct MalformedRespError { // ... } ``` -------------------------------- ### Serve mdbook Documentation Locally Source: https://github.com/nrc/error-docs/blob/main/README.md Serve a local copy of the documentation for previewing using the mdbook serve command. ```bash mdbook serve ``` -------------------------------- ### Build mdbook Documentation Source: https://github.com/nrc/error-docs/blob/main/README.md Build the documentation locally using the mdbook build command. ```bash mdbook build ``` -------------------------------- ### Rust Mocking for Error Handling Tests Source: https://github.com/nrc/error-docs/blob/main/rust-errors/testing.md Demonstrates how to use mock objects to test error recovery paths in Rust. This pattern involves defining a trait and creating mock implementations that return specific results or errors. ```rust fn process_something(thing: impl Thing) -> Result { thing.process() } trait Thing { fn process(&self) -> Result; } #[cfg(test)] mod test { use super::*; // Mock object struct AlwaysZero; impl Thing for AlwaysZero { fn process(&self) -> Result { Ok(0.0) } } // Mock object struct AlwaysErr; impl Thing for AlwaysErr { fn process(&self) -> Result { Err(MyError::IoError) } } #[test] fn process_zero() -> Result<(), MyError> { assert_eq!(process_something(AlwaysZero)?, 0); Ok(()) } #[test] fn process_err() -> Result<(), MyError> { // Note that we test the specific error returned but not the contents of // that error. This should match the guarantees/expectations of `process_something`. assert_matches!(process_something(AlwaysErr), Err(MyError::ProcessError(_))); Ok(()) } } ``` -------------------------------- ### Panic with Arbitrary Data using panic_any Source: https://github.com/nrc/error-docs/blob/main/rust-errors/panic.md The `panic_any` function allows panicking with any type that implements `Any`, not just a string message. ```rust panic_any(MyError::new()); ``` -------------------------------- ### Panic on None or Err with unwrap/expect Source: https://github.com/nrc/error-docs/blob/main/rust-errors/panic.md The `unwrap` and `expect` methods on `Option` and `Result` types will panic if the value is `None` or `Err`, respectively. `expect` allows a custom panic message. ```rust let locked = mutex.lock().unwrap(); ``` ```rust let value = option.expect("expected a value"); ``` -------------------------------- ### Unconditional Panic with panic! Macro Source: https://github.com/nrc/error-docs/blob/main/rust-errors/panic.md Use the `panic!` macro to unconditionally trigger a panic. This is typically used for unrecoverable errors. ```rust panic!("crash and burn"); ``` -------------------------------- ### Handle Result with match Source: https://github.com/nrc/error-docs/blob/main/rust-errors/result-and-error.md Use a `match` expression to explicitly handle both `Ok` and `Err` variants of a `Result`. ```rust fn use_match_to_handle_result(r: Result) { match r { Ok(s) => println!("foo got a string: {s}"), Err(e) => println!("an error occurred: {e}"), } } ``` -------------------------------- ### Conditional Panic with assert_eq Macro Source: https://github.com/nrc/error-docs/blob/main/rust-errors/panic.md The `assert_eq!` macro panics if the two provided expressions are not equal. This is useful for validating conditions. ```rust debug_assert_eq!(left, right, "left and right must be equal"); ``` -------------------------------- ### Testing Error Return Values in Rust Source: https://github.com/nrc/error-docs/blob/main/rust-errors/testing.md Use `is_err`, `is_err_and`, `unwrap_err`, and `assert_eq!` to verify error conditions and their details within Rust tests. This approach provides precise control over error validation. ```rust #[test] fn test_for_errors() { assert!(should_return_any_error().is_err()); assert!(should_return_not_found().is_err_and(|e| e.kind() == ErrorKind::NotFound)); let e = should_return_error_foo().unwrap_err(); assert_eq!(e.kind(), ErrorKind::Foo); assert_eq!(e.err_no(), 42); assert_eq!(e.inner().kind(), ErrorKind::NotFound); } ``` -------------------------------- ### Implementing From Trait for Error Conversion Source: https://github.com/nrc/error-docs/blob/main/error-design/error-type-design.md Implement the `From` trait to enable ergonomic error conversion at API boundaries using the `?` operator. ```Rust use std::io; #[derive(Debug)] enum ApiError { Io(io::Error), Parse, } impl From for ApiError { fn from(err: io::Error) -> ApiError { ApiError::Io(err) } } ``` -------------------------------- ### Map C Error Codes to Rust Result Source: https://github.com/nrc/error-docs/blob/main/rust-errors/interop.md Converts an `isize` C error code into a Rust `Result`. Handles specific negative codes and a catch-all for unknown errors. ```rust fn map_err_code(code: isize) -> Result { match code { c if c >= 0 => Ok(c as usize), -1 => Err(MyError::Foo), -2 => Err(MyError::Bar), -3 | -4 => Err(MyError::Baz), c => Err(MyError::UnknownForeign(c)), } } ``` -------------------------------- ### API Boundary Error Struct with Enum Kind Source: https://github.com/nrc/error-docs/blob/main/error-design/error-type-design.md Illustrates an error structure designed for API boundaries, encapsulating a request and an enum for different error kinds. This separates internal implementation details from the API's error representation. ```rust pub struct MessageError { kind: MessageErrorKind, request: Request, } pub enum MessageErrorKind { Network(IoError), Parse(Option), } enum NetworkError { NotConnected, ConnectionReset, // ... } enum ParseError { Malformed(MalformedRespError), MissingHeader(String), UnknownField(String), } struct MalformedRespError { // ... } ``` -------------------------------- ### Panic on Arithmetic Overflow (Debug Builds) Source: https://github.com/nrc/error-docs/blob/main/rust-errors/panic.md In debug builds, arithmetic overflow or underflow will cause a panic. This behavior is not present in release builds by default. ```rust let a = u32::MAX; let _ = a + 1; ``` -------------------------------- ### Map Result payload with map combinator Source: https://github.com/nrc/error-docs/blob/main/rust-errors/result-and-error.md The `map` combinator applies a function to the `Ok` variant's payload, returning a new `Result`. If the input is `Err`, it remains unchanged. ```rust fn map_a_result(r: Result) -> Result { r.map(|i| i.to_string()) } ``` -------------------------------- ### Panic on Index Out of Bounds Source: https://github.com/nrc/error-docs/blob/main/rust-errors/panic.md Accessing a slice or vector with an index that is out of bounds will cause a panic. ```rust let v = vec![1, 2, 3]; let _ = v[42]; ``` -------------------------------- ### Propagate Result errors with ? Source: https://github.com/nrc/error-docs/blob/main/rust-errors/result-and-error.md The `?` operator unwraps the `Ok` value or immediately returns the `Err` value from the function. This is a concise way to handle fallible operations. ```rust fn use_q_mark(r: Result) -> Result { let i = r?; // Unwraps Ok, returns an Err Ok(i.to_string()) } ``` -------------------------------- ### Single Struct Error Design Source: https://github.com/nrc/error-docs/blob/main/error-design/error-type-design.md Illustrates a common single struct error design pattern. It uses a struct to hold error details and a C-like enum for error kinds. ```Rust pub struct MyError { kind: ErrorKind, source: Box, message: Option, request: Option, } pub enum ErrorKind { Network, MalformedResponse, MissingHeader, UnknownField, // This lets us handle any kind of error without adding new error kinds. Other, } ``` -------------------------------- ### Manual Error Propagation in Rust Source: https://github.com/nrc/error-docs/blob/main/recovery.md Manually return an error to the caller in Rust. This is often used in conjunction with `match` to handle some errors while propagating others. ```rust fn process_data() -> Result<(), DataError> { match some_operation() { Ok(value) => { // Process value Ok(()) } Err(e) => { // Handle or propagate the error return Err(DataError::ProcessingFailed(e)); } } } ``` -------------------------------- ### Propagate and convert Result errors with ? Source: https://github.com/nrc/error-docs/blob/main/rust-errors/result-and-error.md The `?` operator can implicitly convert error types using `From::from` if the target error type implements it. This allows for flexible error handling across different error types. ```rust fn use_q_mark_with_from(r: Result) -> Result { let i = r?; // ... } ``` -------------------------------- ### Marking Error Enums as Non-Exhaustive Source: https://github.com/nrc/error-docs/blob/main/error-design/error-type-design.md Use `#[non_exhaustive]` on error enums to allow adding new variants in the future without breaking existing code. ```Rust #[non_exhaustive] enum MyError { VariantA, VariantB, } ``` -------------------------------- ### Propagating Errors with `?` in Rust Source: https://github.com/nrc/error-docs/blob/main/recovery.md Use the `?` operator for implicit error conversion and propagation in Rust. This is a concise way to return an error to the caller. ```rust fn read_file() -> Result { let mut file = File::open("hello.txt")?; let mut contents = String::new(); file.read_to_string(&mut contents)?; Ok(contents) } ``` -------------------------------- ### Enum for Reportable Errors Source: https://github.com/nrc/error-docs/blob/main/error-design/error-type-design.md Defines an enum for errors that should be reported, including specific header/field errors, failed retries, or other general errors. ```rust pub enum Reportable { MissingHeader(String), UnknownField(String), RetryFailed(Retryable), NotReportable(Box), } // Assuming Retryable is defined elsewhere as in the previous example ``` -------------------------------- ### Enum for Retryable Errors Source: https://github.com/nrc/error-docs/blob/main/error-design/error-type-design.md Defines an enum to categorize errors that can be retried, including network issues, malformed responses, or other errors boxed as a general error type. ```rust pub enum Retryable { Network(IoError, Request), Malformed(MalformedRespError), NotRetryable(Box), } pub struct MalformedRespError { // ... } ``` -------------------------------- ### Checking if Current Thread is Panicking Source: https://github.com/nrc/error-docs/blob/main/rust-errors/panic.md The `std::thread::panicking` function returns `true` if the current thread is unwinding due to a panic, and `false` otherwise. This is crucial for preventing double panics. ```rust if std::thread::panicking() { // Current thread is already panicking } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.