[−][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
Working with Results and Options
While the chain method adds context to error types directly, we
can do a similar thing with the Err value within a Result with
the chain_err method.
use std::fs::File; fn main() -> Result<(), StrError> { let file = "missing-file"; let _ = File::open(file) // returns a Result .chain_err(format!("Failed to open file {}", file))?; // main exits here Ok(()) }
gives output
Error: Failed to open file missing-file
Caused by: No such file or directory (os error 2)
With Options no special method is needed to transform one into a
Result with a StrError. We can just use ok_or and
ok_or_else with a newly created one.
However, it is often sufficient to pass just a &str or
String. This gives a Result containing a &str or String
for its Err value, but when used with the ? operator it gets
converted to a StrError. This works because StrError
implements From<&str> and From<String>.
use std::env; fn main() -> Result<(), StrError> { let _ = env::var_os("MISSING_VAR") // returns an Option .ok_or("Environment variable MISSING_VAR not found")?; // main exits here Ok(()) }
gives
Error: Environment variable MISSING_VAR not found
From conversions for other error types
From conversions are implemented for most of the standard
library error types, so you can return a Result containing one
directly from a function that returns a Result containing a
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)
As mentioned when discussing Options, From conversions are
also implemented for &str and String.
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 one containing a StrError. Of course
you may choose to return a Result containing a
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 |
Macros
| eformat | A macro for creating a |
Structs
| Iter | An iterator producing a reference to a |
| StrError | A string-based error type implementing |
Traits
| ErrorChainExt | Trait providing |
| ResultChainErrExt | Trait providing |
| StringToErrorExt | Trait providing |