error-chain icon indicating copy to clipboard operation
error-chain copied to clipboard

Matching on causes?

Open bennofs opened this issue 8 years ago • 11 comments
trafficstars

I currently have error chain setup like this:

/// main.rs
use db;

error_chain! {
  errors {
    DbRead {
// ...
    }
  }
}
/// db.rs
error_chain! {
  // ...
  foreign_links {
    Io(io::Error);
  }
}

How do I implement this:

I want to give a special error message / return different exit code / handle differently when there is a DbRead error where the cause is the IO error file not found.

bennofs avatar Aug 01 '17 14:08 bennofs

For now, I don't think you can. You would need a Any bound on the cause, I think.

Yamakaky avatar Aug 01 '17 16:08 Yamakaky

@Yamakaky any suggestions on how to deal with this case? Do I need to use a "flat" error hierarchy?

bennofs avatar Aug 01 '17 16:08 bennofs

Silly me, you can. See file:///home/yamakaky/dev/rust/error-chain/target/doc/error_chain/example_generated/enum.ErrorKind.html, Inner variant. For your own code, try cargo doc to see the hierarchy

Yamakaky avatar Aug 01 '17 20:08 Yamakaky

The real link (for those who don't have access to Yamakaky's computer)

Cobrand avatar Aug 02 '17 05:08 Cobrand

ahahahahah

Yamakaky avatar Aug 02 '17 06:08 Yamakaky

@Yamakaky That would only work if I used links I believe.

bennofs avatar Aug 02 '17 07:08 bennofs

Yes. Can't you do this?

Yamakaky avatar Aug 02 '17 19:08 Yamakaky

I have the same issue:

error_chain! {
	foreign_links {
		Io(io::Error);
	}
}

fn load<P: AsRef<Path>>(path: P) -> Result<Database, Error> {
	let mut file = fs::File::open(path).chain_err(|| "Cannot open database")?;
	// logic...
}

fn main() {
	match load("file.txt") {
		// I would like to match io::ErrorKind::NotFound  here, but it's not possible to get internal error
	}
}

debris avatar Aug 04 '17 15:08 debris

@Yamakaky the problem with using links is that I won't get nice hierarchical error messages for the remaining, non special causes. For example, I wouldn't be able to get:

Error: database read failed
Cause: more specific error message

@debris I think that is a different issue. If I am not mistaken, foreign_links creates a new error kind variant with the foreign error attached. Can you match on that?

bennofs avatar Aug 04 '17 16:08 bennofs

@bennofs so how does one match against foreign_links? I tried to iterate over errors but then I can't match.

pronebird avatar Sep 13 '17 13:09 pronebird

@pronebird like this:

#[macro_use] extern crate error_chain;

use std::io;
error_chain! {
	  foreign_links {
		    Io(io::Error);
	  }
}

fn test() -> Result<()> {
    let mut line = String::new();
    io::stdin().read_line(&mut line)?;
    Ok(())
}


fn main() {
    if let Err(e) = test() {
        match *e.kind() {
            ErrorKind::Io(ref e) => {
                let x: &io::Error = e;
               //... 
            },
            _ => {}
        }
    }
}

bennofs avatar Sep 13 '17 13:09 bennofs