Generic error handling

Hello,

To start with my background, I come from error handling in Go and I've not used generics that much in the past. I'm doing my first from-scratch rust project.

I'm successfully returning errors of different types in my implementation, but I struggle to understand why this code is valid.

I have my own trait like this

pub trait List<E: Error> {
    fn foo() -> Result<(), E>;
}

Implemented by this pseudo code, I hope the important bits are there:

impl<E> List<E> for Bar
where
    E: Error + From<fjall::Error> + From<bincode::Error>,
{
    fn foo(&self) -> Result<(), E> {
        let value = fjall::do_database_things()?;
        bincode::decode(value)?;
        Ok(())
    }
}

In my head, the trait bounds says the concrete error type in E needs to implement both From<fjall::Error> and From<bincode::Error>.

fjall and bincode know nothing about each other, how is this then satisfied by the compiler?
How can the fjall error also be satisfying the From<bincode:Error>?

Your code looks fishy to me and the fact that you chose E to be generic instead of a specific type might be caused by a misunderstanding. Maybe this clears when your questions are answered,

fjall and bincode know nothing about each other, how is this then satisfied by the compiler?

This is not satisfied automagically since there is no concrete error type E in the code you provided. If you want to call <Bar as List<E>>::foo you need to supply the concrete type E which fulfills the requirements.

If you write application code this can be a catch all error type like anyhow::Error. In library code you would typically include your own error type which encodes more specific context information and can be handled appropriatly by the user like

pub enum ListError {
    DataBase(fjall::Error),
    CorruptionError(bincode::Error),
}

The crate thiserror helps you to implement useful Display and Error implementations for this type.

2 Likes

Thank you, I think I've jumped to conclusions when the cargo check passed but before I've actually tried to use the implementation, thus there's no concrete type for E yet.

The ListError approach is probably what I will be adding