Usually, there are two ways to deal with this:
- 'Erase' the type by using
dyn Error:
This is useful if you only care about the message the errors might return, and not their actual type.fn main() -> Result<(), Box<dyn std::error::Error>> { let x = f1()?; let y = f2()?; let z = f3()?; Ok(()) } - Create an enum that contains the 3 types:
Since this is a bit tedious, you can use the crate thiserror to make the process easierenum MyError { Error1(Error1), Error2(Error2), Error3(Error3), } impl From<Error1> for MyError { ... } impl From<Error2> for MyError { ... } impl From<Error3> for MyError { ... } fn main() -> Result<(), MyError> { let x = f1()?; let y = f2()?; let z = f3()?; Ok(()) }