A custom error type names the failures an operation can return. In Rust, an enum works well when an operation has several possible failures: each variant gives callers a case they can handle separately. The conventional name `Error` is not special; it is an ordinary programmer-defined type. section 2.5.4
Start with one failure
A FizzBuzz function that rejects negative input can define `enum Error { GotNegative }` and return `Result<FizzBuzzValue, Error>`. It returns `Err(Error::GotNegative)` for negative input. Its caller can match that variant to print a specific message, rather than treating every failure alike. section 2.5.4
Use `?` when a function should pass an error to its caller without inspecting it. For example, `let result = fizzbuzz(i)?;` replaces a match that extracts `Ok` or returns `Err`. This forwarding is an explicit choice in a function that returns a compatible `Result`. section 2.5.4 section 2.6
Grow the enum as failures appear
An arithmetic evaluator begins with an empty `Error` enum, then adds `InvalidNumber` when parsing can fail. A stack operation adds `PopFromEmptyStack` and returns `Result<i32, Error>`; the evaluator uses `stack.pop()?` to pass that failure onward. Its C-facing `solve` function keeps the Rust `Result` inside the library and converts success or failure to an integer return code. section 3.2.3
A public function cannot expose a private error type in its return value. When `evaluate` becomes `pub fn evaluate(problem: &str) -> Result<i32, Error>`, its `Error` enum must also become public so callers can identify the failure. If an error must be printed with `{}`, implementing `Display` for the type is considered best practice. section 4.5 section 3.3




