I have some difficulties right now to propagate a custom error with the ?
operator up to a higher caller.
My lib-specific result type is defined like so:
pub type AlsError = Box<dyn std::error::Error + Send + Sync>;
pub type AlsResult<T> = Result<T, AlsError>;
The following code produces the compilation error:
// Some type for a network communication protocol
pub struct ComHeader {
...
transaction_no: u32,
...
}
// Parsing some specific bytes received from a `TcpStream` to an instance of `ComHeader`
impl TryFrom<&[u8]> for ComHeader {
type Error = AlsError;
fn try_from(buffer: &[u8]) -> AlsResult<Self> {
...
let transaction_no = u32::from_be_bytes(
buffer[up_to_trans_no..up_to_trans_name]
.try_into()
// I want to propagate a custom error here, as the original one lacks some crucial information
.map_err(|_| {
Err(throw!(
2,
AlsErrorKind::TypeParse,
format!(
"Parse for variable 'transaction_no' failed for value `{:?}`",
buffer[up_to_trans_no..up_to_trans_name].to_vec()
)
))
})?, // Row 166
);
...
Ok(ComHeader {
...
transaction_no,
...
})
}
}
But the compiler complains while building the library:
error[E0277]: the trait bound `Result<_, Box<dyn std::error::Error + Send + Sync>>: std::error::Error` is not satisfied
--> src/net/base/com_header.rs:166:11
|
166 | })?,
| ^ the trait `std::error::Error` is not implemented for `Result<_, Box<dyn std::error::Error + Send + Sync>>`
|
= note: required because of the requirements on the impl of `From<Result<_, Box<dyn std::error::Error + Send + Sync>>>` for `Box<dyn std::error::Error + Send + Sync>`
= note: required because of the requirements on the impl of `FromResidual<Result<Infallible, Result<_, Box<dyn std::error::Error + Send + Sync>>>>` for `Result<com_header::ComHeader, Box<dyn std::error::Error + Send + Sync>>`
What I don't understand here is that:
- The error returned by the
throw!
macro implementsstd::error::Error
, so why is this trait bound not satisfied? - Why does Rust check if the type
Result<_, Box<dyn std::error::Error + Send + Sync>>
implementsError
, when instead Rust should check the Result'sErr
variant instead?
Thanks in advance!