[][src]Crate strerror

A string-based error type.

Introduction

This crate provides a string-based error type, StrError, that implements std::error::Error. StrErrors behave much like Strings, except they may contain another error boxed inside them, known as the "source" or "cause". Since the source can have a source itself, sources form chains of errors, each error adding context to the preceeding one.

When a StrError is returned from main, its Debug implementation causes the output of a CLI application to look like this

Error: ...
Caused by: ...
Caused by: ...
...

Each "Caused by:" line corresponds to a boxed error in the chain of sources.

The prelude

This crate has a prelude to bring in all the things you need at once.

use strerror::prelude::*;

Because some of the crate's functionality is contained in extension traits, this is quite useful. The examples below all assume the prelude is used.

Creating StrErrors

As with Strings, there are quite a few ways to create a StrError. Some have a String equivalent so we present these alongside each other.

// String                             // StrError
let str1 = "Error!".to_string();      let err1 = "Error!".to_error();
let str2 = String::from("Error!");    let err2 = StrError::from("Error!");
let str3: String = "Error!".into();   let err3: StrError = "Error!".into();
let str4 = format!("Error! #{}", 1);  let err4 = eformat!("Error! #{}", 1);

The above lines all create StrErrors without a "source" or "cause". Next we show two equivalent ways to create a StrError containing a source. The StrError takes ownership of the source which may or may not be another StrError.

use std::io::Error as IoError;

let source1 = IoError::from_raw_os_error(5);
let err1 = StrError::from_error(source1, "I/O error occurred");

let source2 = IoError::from_raw_os_error(5);
let err2 = source2.chain("I/O error occurred");

The advantage of the second way using the chain method comes from the fact that, in chaining methods together, an error chain itself can be created.

fn main() -> Result<(), StrError> {
    let err = "Base error".to_error()
        .chain("Higher level error")
        .chain("Application error");
    Err(err)
}

gives output

Error: Application error
Caused by: Higher level error
Caused by: Base error

Returning Results

While the chain method adds context to error types directly, we can do a similar thing with the Err values contained within Results, with the chain_err method.

use std::fs::File;

fn main() -> Result<(), StrError> {
    let file = "missing-file";
    let _ = File::open(file)                             // a Result
        .chain_err(format!("Failed to open {}", file))?; // main exits here
    Ok(())
}

gives output

Error: Failed to open missing-file
Caused by: No such file or directory (os error 2)

The Result is converted to the correct type by chain_err and context is applied to the boxed error.

Converting Options

Sometimes None represents an application error and it is desirable to convert an Option<T> into a Result<T, StrError>. There is no special method needed in this case and you can use ok_or/ok_or_else with a new StrError (created using to_error, for example).

use std::env;

fn main() -> Result<(), StrError> {
    let _ = env::var_os("MISSING_VAR")                       // an Option
        .ok_or_else(|| "MISSING_VAR not found".to_error())?; // main exits here
    Ok(())
}

gives output

Error: MISSING_VAR not found

However, if your containing function returns a Result<T, StrError>, it is sufficient to pass just a &str or String to ok_or/ok_or_else. This produces a Result<T, &str> or Result<T, String>, but when used with the ? operator it is converted to a Result<T, StrError>. This works because StrError implements From<&str> and From<String>.

use std::env;

fn main() -> Result<(), StrError> {
    let _ = env::var_os("MISSING_VAR")
        .ok_or("MISSING_VAR not found")?;
    Ok(())
}

From conversions

From conversions are implemented for most of the standard library error types, so you can return a Result containing one directly from a function returning a Result<T, StrError>, using the ? operator.

use std::fs::File;

fn main() -> Result<(), StrError> {
    let file = "missing-file";
    let _ = File::open(file)?; // main exits here
    Ok(())
}

gives output

Error: std::io::Error
Caused by: No such file or directory (os error 2)

From conversions are also implemented for &str and String, as discussed above.

However, for other error types, if you wish to use the ? operator, you will first need to call the chain_err method to convert the Result into a Result<T, StrError>. Of course you may choose to return a Result<T, Box<dyn std::error::Error>> from your function instead, for which ? will work for all error types.

Deref

StrErrors deref to a String, so you can use many of the usual String methods.

fn main() -> Result<(), StrError> {
    let mut err = "This is".to_error();
    *err += " an error";
    err.push_str(" message");
    Err(err)
}

gives output

Error: This is an error message

Iterating through the source chain

A reference to a StrError can be iterated over to examine its chain of boxed sources.

use std::io::Error as IoError;

fn main() -> Result<(), StrError> {
    let err = IoError::from_raw_os_error(5)
        .chain("Failure reading disk")
        .chain("Application error");
    for e in &err {
        println!(
            "Error: {:31} Is StrError?: {}",
            e,
            e.downcast_ref::<StrError>().is_some()
        );
    }
    Ok(())
}

gives output

Error: Application error               Is StrError?: true
Error: Failure reading disk            Is StrError?: true
Error: Input/output error (os error 5) Is StrError?: false

Modules

prelude

Reexports of eformat, ErrorChainExt, ResultChainErrExt, StrError and StringToErrorExt.

Macros

eformat

A macro for creating a StrError using interpolation of runtime expressions (like format!).

Structs

Iter

An iterator producing a reference to a StrError (as a trait object), followed by its chain of sources.

StrError

A string-based error type implementing std::error::Error.

Traits

ErrorChainExt

Trait providing chain for converting an error of any type to a StrError.

ResultChainErrExt

Trait providing chain_err for mapping the Err value within a Result to a StrError.

StringToErrorExt

Trait providing to_error for converting a String or &str to a StrError.