-
Notifications
You must be signed in to change notification settings - Fork 216
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
initial draft of notion failure trait and types
- Loading branch information
Showing
2 changed files
with
111 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,110 @@ | ||
use std::convert::From; | ||
use std::fmt::{self, Display}; | ||
|
||
use failure::{self, Fail, Backtrace}; | ||
|
||
/// The failure trait for all Notion errors. | ||
pub trait NotionFail: Fail { | ||
/// Indicates whether this error has a message suitable for reporting to an end-user. | ||
fn is_user_friendly(&self) -> bool; | ||
|
||
/// Indicates the process exit code that should be returned if the process exits with this error. | ||
fn exit_code(&self) -> i32; | ||
} | ||
|
||
/// The `NotionError` type, which can contain any Notion failure. | ||
#[derive(Fail, Debug)] | ||
#[fail(display = "{}", error)] | ||
pub struct NotionError { | ||
error: failure::Error, | ||
user_friendly: bool, | ||
exit_code: i32 | ||
} | ||
|
||
impl NotionError { | ||
/// Returns a reference to the underlying failure of this error. | ||
pub fn as_fail(&self) -> &Fail { | ||
self.error.cause() | ||
} | ||
|
||
/// Gets a reference to the `Backtrace` for this error. | ||
pub fn backtrace(&self) -> &Backtrace { | ||
self.error.backtrace() | ||
} | ||
|
||
/// Attempts to downcast this error to a particular `NotionFail` type by reference. | ||
/// | ||
/// If the underlying error is not of type `T`, this will return `None`. | ||
pub fn downcast_ref<T: NotionFail>(&self) -> Option<&T> { | ||
self.error.downcast_ref() | ||
} | ||
|
||
/// Attempts to downcast this error to a particular `NotionFail` type by mutable reference. | ||
/// | ||
/// If the underlying error is not of type `T`, this will return `None`. | ||
pub fn downcast_mut<T: NotionFail>(&mut self) -> Option<&mut T> { | ||
self.error.downcast_mut() | ||
} | ||
} | ||
|
||
impl<T: NotionFail> From<T> for NotionError { | ||
fn from(failure: T) -> Self { | ||
let user_friendly = failure.is_user_friendly(); | ||
let exit_code = failure.exit_code(); | ||
NotionError { | ||
error: failure.into(), | ||
user_friendly, | ||
exit_code | ||
} | ||
} | ||
} | ||
|
||
/// An extension trait allowing any failure, including failures from external libraries, | ||
/// to be converted to a Notion error. This marks the error as an unknown error, i.e. | ||
/// a non-user-friendly error. | ||
pub trait FailExt { | ||
fn unknown(self) -> NotionError; | ||
} | ||
|
||
/// A wrapper type for unknown errors. | ||
#[derive(Debug)] | ||
struct UnknownNotionError { | ||
error: failure::Error | ||
} | ||
|
||
impl Display for UnknownNotionError { | ||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | ||
write!(f, "An unknown error has occurred") | ||
} | ||
} | ||
|
||
impl Fail for UnknownNotionError { | ||
fn cause(&self) -> Option<&Fail> { | ||
Some(self.error.cause()) | ||
} | ||
|
||
fn backtrace(&self) -> Option<&Backtrace> { | ||
Some(self.error.backtrace()) | ||
} | ||
} | ||
|
||
impl NotionFail for UnknownNotionError { | ||
fn is_user_friendly(&self) -> bool { false } | ||
fn exit_code(&self) -> i32 { 1 } | ||
} | ||
|
||
impl<T: Fail> FailExt for T { | ||
fn unknown(self) -> NotionError { | ||
UnknownNotionError { error: self.into() }.into() | ||
} | ||
} | ||
|
||
impl<D: NotionFail> NotionFail for failure::Context<D> { | ||
fn is_user_friendly(&self) -> bool { | ||
self.get_context().is_user_friendly() | ||
} | ||
|
||
fn exit_code(&self) -> i32 { | ||
self.get_context().exit_code() | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters