Custom error does not propagate for nested data types
wangbj opened this issue · 0 comments
wangbj commented
Given below example:
#![allow(dead_code)]
use std::io;
use std::fmt;
use binrw::BinRead;
#[derive(Clone, Copy, Debug)]
#[repr(u32)]
enum Error {
Failed = 1,
}
impl std::error::Error for Error {}
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "Error::Failed")
}
}
#[derive(BinRead, Debug)]
struct MyStruct {
#[br(assert(version != 0, Error::Failed))]
version: u32,
}
#[derive(BinRead, Debug)]
struct SizedStruct {
size: u32,
inner: MyStruct,
}
fn main() -> anyhow::Result<()> {
let mut buf = io::Cursor::new(vec![0u8; 8]);
let s: SizedStruct = BinRead::read_ne(&mut buf).map_err(|err| {
assert!(err.custom_err::<Error>().is_some());
err
})?;
println!("s = {:?}", s);
Ok(())
}
The code would fail at assertion failure, because the error type is not a custom_err
, with the assert removed, it will print:
Error:
╺━━━━━━━━━━━━━━━━━━━━┅ Backtrace ┅━━━━━━━━━━━━━━━━━━━━╸
0: Error: Error::Failed at 0x4
While parsing field 'inner' in SizedStruct
at src/main.rs:29
╺━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╸
Which is a backtrace error, or binrw::error::Error::Backtrace(_)
to be precise; while I was expecting binrw::error::Error:: Custom
instead. Notice if I call read_ne
on MyStruct
the function could indeed return custom error, which is inconsistent, hence I feel like this is a bug in binrw.