Adding your own errors to Result?

Beginner here. I'm confused about error handing. I'm creating a function:

fn from_row(row: rusqlite::Row) -> Result<Card> { ... }

The Card is my struct. Result is a type alias in rusqlite that has the error part set to rusqlite.Error. Following example code, I have expressions like row.get(0)? that will return the error variant of the Result if they fail. That worked fine at first.

But as I add to my function, I find new ways to fail. For example, I might get a valid String from the row, but fail to parse it how I expect. If this were Java I would just throw some type of Exception and effectively add to the types of errors that can be "returned" / thrown. But here, I can't add to the enum defined in rusqlite. So what do you normally do? Do you define a new Error type? Like:

enum MyError {
    SqlError(rusqlite.Error),
    NewWayToFail1,
    NewWayToFail2,  // better names of course
    ...
}
fn from_row(row: rusqlite.Row) -> Result<Card, MyError> { ... }

I'm thinking the row.get(0)? won't work then. ?

I like the MyError enum approach. If you implement From<rusqlite::Error> for MyError, row.get(0)? will still work fine.

6 Likes

You're on the right track. To make the question mark operator work, you just need a From implementation:

impl From<rusqlite::Error> for MyError {
  fn from(x: rusqlite::Error) -> MyError {
    MyError::SqlError(x)
  }
}
3 Likes

For a deep dive into error handling in Rust, I recommend this article by Sabrina Jewson: Modular Errors in Rust - Sabrina Jewson

1 Like