Idiomatic way of handling error conversions


I am wondering if my current approach is correct for some Error handling or (if it’s ok) which one of 2 options should I choose. Let me explain:

I have a RepositoryError ( hiding all the Errors, wether they are coming from an underlying implementation or custom error ).
So suppose we take the Memory implementation of the Repository, which is using RwLock. I want to handle the RwLock PoisonError and convert it into a MemoryRepositoryError which can be then supplied to RositoryError::PersistenceError(Box<dyn std::error::Error + Send>) (or maybe directly supply the PoisonError here as somebody can actually supply it as it is, as it’s a std::error::Error).

This means that my methods return: Result<..., RositoryError>

So given this setup, I want to handle the Poison error, by either doing 1 of 2 things:

  1. Use From<PoisonError<....>> for RepositoryError which in terms will return a RositoryError::PersistenceError<Box<MemoryRepositoryError>>, but then when we use it, it’s quite vague what’s happening when we call err.into() the fact that underneath is using a MemoryRepositoryError is not visible.
  2. From<PoisonError<....>> for MemoryRepositoryError and then have a From<MemoryRepositoryError> for RepositoryError

These impl will live in the “memory” persistence module, just to keep in mind.

For me 1. looks very appealing, but then I don’t like the fact that it’s a bit magical and not obvious + the fact that it’s a std::error:Error to which you can supply PoisonError directly :sweat_smile:. But then it can also be substituted with a custom marker trait, maybe?!?
Or maybe I am handling this the wrong way as a whole?

EDIT: Apparently (it’s actually obvious :grimacing: ) the RwLockWriteGuard & RwLockWriteGuard can’t be send across threads (!Send) so I can’t actually pass it directly to RepositoryError::PersistenceError.