[−][src]Crate error_context
This crate provides methods and types that help with adding additional context information to error types.
Usage
There are two ways to add context information to your error types:
- by extending your error type with a filed that will store the context information and then adding context to the error value,
- wrapping any error type together with the context information and then converting this boundle to type that can store the error and context.
This crate provides types, traits and extension methods designed to help with the above tasks.
It is recommended to import all the types and traits via perlude module: use error_type::prelude::*
.
Adding context to types that can collect context
If your type can collect context information you can implement WithContext
trait for it. By doing so you enable some of the provided extension methods to work with your type.
Directly to value
You can add context to value of your error with .with_context(context)
.
To error wrapped in Result
Use .error_while(context)
method on Result
value to add context to error value of type that implements WithContext
.
You can also use in_context_of(context, closure)
function to add context to result of provided closure. You can use ?
within the closure to control the flow.
There is also .error_while_with(context_function)
and in_context_of_with(context_function, closure)
variants that can be used to defer construction of context to error path.
Adding context to other types
External error types may not support adding context.
The ErrorContext
type can be used to wrap error value and context information together.
This type implements WithContext
and adding further context information will result in wrapping with another layer of ErrorContext
type.
The main use case for this method is to wrap error in one or more layers of context and then convert them to your own error type consuming
the error and the context information using From
trait.
This enables use of ?
to convert external error types with added context to your error type.
Directly to value
You can wrap any type in ErrorContext
type using .wrap_context(context)
method.
To error wrapped in Result
When working with Result
value you can wrap error value in ErrorContext
using .wrap_error_while(context)
.
There is also .wrap_error_while_with(context_function)
and wrap_in_context_of_with(context_function, closure)
variants that can be used to defer construction of context to error path.
Using ErrorNoContext
You can also use .to_root_cause()
directly on error value or .map_error_context()
on Result
to wrap error type in ErrorNoContext
.
Adding context information to ErrorNoContext
converts it into ErrorContext
.
ErrorNoContext
is intended to be used within function scope to enable functions and methods that work with WithContext
to add
context information bafore error is returned.
Usage example
In this example we will create our own error type called MyError
.
We will wrap extra context information to std::io::Error
value using .wrap_error_while(context)
and as another example using .wrap_in_context_of(context, closure)
.
Finally by implementing From<ErrorContext<io::Error, &'static str>>
for MyError
we can use ?
operator to convert this error to MyError
persisting the context information added.
use error_context::prelude::*; use std::io; enum MyError { IoError(io::Error, &'static str), } impl From<ErrorContext<io::Error, &'static str>> for MyError { fn from(error: ErrorContext<io::Error, &'static str>) -> MyError { MyError::IoError(error.error, error.context) } } fn work_with_file() -> Result<(), MyError> { Err(io::Error::new(io::ErrorKind::InvalidInput, "boom!")) .wrap_error_while("working with file")?; Ok(()) } match work_with_file().unwrap_err() { MyError::IoError(_, "working with file") => (), _ => panic!("wrong context"), } fn do_stuff() -> Result<(), MyError> { wrap_in_context_of("doing stuff", || { Err(io::Error::new(io::ErrorKind::InvalidInput, "boom!"))?; Ok(()) })?; Ok(()) } match do_stuff().unwrap_err() { MyError::IoError(_, "doing stuff") => (), _ => panic!("wrong context"), }
Usage guidelines
- Use error context to provide information about which good program path was taken that lead to an error, e.g: "while parsing filed x of message type y".
- Error context should provide detail for the end user who sees the error message and not be used to distinguish between two different errors in code - use
Display
types like&'static str
as context type. - Don't add errors or error path information to context - this should be part of the error type, in particular its
Display
andError::source
implementation. - Don't add arguments of function call you are rising error from to the context - this should be responsibility of the caller - otherwise it would be difficult to
avoid non-
'static
references or allocations on error path and avoid showing sensitive data to end user, e.g. SQL query text or passwords. - Don't put non-
'static
references to context or the error value cannot be bubbled up easily or returned asError::source
.
Modules
prelude | Includes |
Structs
ErrorContext | Wrap error value together with context information |
ErrorNoContext | Wrap value in |
Traits
MapErrorNoContext | Map error caring type by wrapping it's error value in |
ResultErrorWhile | Add context to error carried by another type like |
ResultErrorWhileWrap |
|
ToErrorNoContext | Wrap value with |
WithContext | Add context to object |
WrapContext | Wrap value in type with context information |
Functions
in_context_of | Executes closure adding context to returned error value with |
in_context_of_with | Executes closure adding context to returned error value with |
wrap_in_context_of | Executes closure adding context to returned error value by wrapping it in |
wrap_in_context_of_with | Executes closure adding context to returned error value by wrapping it in |