Skip to content

Instantly share code, notes, and snippets.

@FauxFaux
Created June 20, 2017 08:03
Show Gist options
  • Save FauxFaux/7a2889b9aa0cf2246e5bde5c7bc0b17f to your computer and use it in GitHub Desktop.
Save FauxFaux/7a2889b9aa0cf2246e5bde5c7bc0b17f to your computer and use it in GitHub Desktop.
#[macro_use]
extern crate error_chain;
use errors::*;
fn call_john() -> Result<()> {
john::useful()
.chain_err(|| "calling useful")
?;
Ok(())
}
fn run() -> Result<()> {
call_john()?;
Ok(())
}
mod errors {
error_chain! {
foreign_links {
John(::john::JohnError);
}
}
}
fn main() {
let full_err = run().unwrap_err();
println!("Full error: {:?}", full_err);
let final_cause = full_err.iter().last().unwrap();
// Ignore this line! Honest. It's fine. https://github.com/rust-lang/rust/issues/35943
let final_cause: &'static std::error::Error = unsafe { std::mem::transmute(final_cause) };
match final_cause.downcast_ref::<errors::Error>() {
Some(our_err) => {
match *our_err.kind() {
ErrorKind::Msg(ref m) => {
println!("Destructured, a message: {}", m)
}
ErrorKind::John(ref john_error) => {
println!("Destructured, John was guilty! {:?}", john_error)
}
}
}
None => {
println!("Destructuring failed: Wtf! What is this?! {:?}", final_cause)
}
}
}
mod john {
pub fn useful() -> Result<(), JohnError> {
Err(JohnError::CouldNotBeBothered)
}
#[derive(Debug)]
pub enum JohnError {
CouldNotBeBothered,
Whatever,
}
use ::std::error::Error;
use ::std::fmt;
impl Error for JohnError {
fn description(&self) -> &str {
"whatevs"
}
fn cause(&self) -> Option<&Error> {
None
}
}
impl fmt::Display for JohnError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{:?}", self)
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment