Reputation: 95
When trying to open a broken epub/ZIP file with epub-rs, the zip-rs crate error (which doesn't use Failure) is wrapped into a failure::Error
by epub-rs. I want to handle each error type of zip-rs with an distinct error handler and need a way to match against the underlying error. How can I retrieve it from Failure?
fn main() {
match epub::doc::EpubDoc::new("a.epub") {
Ok(epub) => // do something with the epub
Err(error) => {
// handle errors
}
}
}
error.downcast::<zip::result::ZipError>()
fails and error.downcast_ref()
returns None.
Upvotes: 0
Views: 2207
Reputation: 431011
You can downcast from a Failure Error
into another type that implements Fail
by using one of three functions:
use failure; // 0.1.5
use std::{fs, io};
fn generate() -> Result<(), failure::Error> {
fs::read_to_string("/this/does/not/exist")?;
Ok(())
}
fn main() {
match generate() {
Ok(_) => panic!("Should have an error"),
Err(e) => match e.downcast_ref::<io::Error>() {
Some(e) => println!("Got an io::Error: {}", e),
None => panic!("Could not downcast"),
},
}
}
For your specific case, I'm guessing that you are either running into mismatched dependency versions (see Why is a trait not implemented for a type that clearly has it implemented? for examples and techniques on how to track this down) or that you simply are getting the wrong error type. For example, a missing file is actually an std::io::Error
:
// epub = "1.2.0"
// zip = "0.4.2"
// failure = "0.1.5"
use std::io;
fn main() {
if let Err(error) = epub::doc::EpubDoc::new("a.epub") {
match error.downcast_ref::<io::Error>() {
Some(i) => println!("IO error: {}", i),
None => {
panic!("Other error: {} {:?}", error, error);
}
}
}
}
Upvotes: 2