Result<T, String> is, generally speaking, bad. It’s lazy and it’s not idiomatic; if you want to fail with a descriptive error, you should instead use a type that implements std::error::Error. Unfortunately, there are times when it should be okay to be lazy. Maybe you want a descriptive error but don’t need to handle different kinds of errors, or you have a function that calls other functions that return a Result, but the error type is different in each case. For those situations (and probably others I haven’t thought of), you want a general-purpose error type, which libstd doesn’t currently have. Therefore, I’d like to propose the following additions to libstd:
- A new type,
std::error::WrappedError, which implementsstd::error::Errorsuch that calls to those methods are direct calls to an innerErrorobject:
use std::error::Error;
pub struct WrappedError { ... }
impl WrappedError {
pub fn new<T>(error: T) -> WrappedError where T: Into<Box<Error>> { ... }
}
impl Error for WrappedError { ... }
- A new type,
std::error::GeneralError, which holds aStringand anOption<Box<Error>>, and implementsstd::error::Errorsuch thatGeneralError::description()returns the held string, andGeneralError::cause()returns an optional reference to the held error:
use std::error::Error;
pub struct GeneralError { ... }
impl GeneralError {
pub fn new<T>(description: T) where T: Into<String> { ... }
pub fn with_cause<T, C>(description: T, cause: C) where T: Into<String>, C: Into<Box<Error>> { ... }
}
What do you guys think?