0
votes

I use diesel and postgres for my rust project.

The problem i am struggling with right now is when i insert_into the table there are different errors that can occur and i want to take different actions for the different error types.

Those are the Errors: Diesel DatabaseErrorKind

And i want to do something like this (source):

use std::fs::File;
use std::io::ErrorKind;

fn main() {
    let f = File::open("hello.txt");

    let f = match f {
        Ok(file) => file,
        Err(error) => match error.kind() {
            ErrorKind::NotFound => match File::create("hello.txt") {
                Ok(fc) => fc,
                Err(e) => panic!("Problem creating the file: {:?}", e),
            },
            other_error => {
                panic!("Problem opening the file: {:?}", other_error)
            }
        },
    };
}

The problem is that there is no error.kind() for the diesel error.

1

1 Answers

1
votes

The "error kind" pattern is useful in some cases where all the errors are basically the same or have lots of common information / payload and limited to no individuality aside from, well, the error kind. Diesel uses that pattern for database errors (hence DatabaseErrorKind) because DB engines generally just provide an error identifier / code and a bunch of metadata, but which error gets which metadata is often undocumented and variable over time.

However at the toplevel Diesel knows much more precisely what the errors are and what each error can signal, so it uses a direct error enun.

So you just... match on that instead of matching on the errorkind:

match r {
    Ok(r) => ...,
    Err(e) => match e {
        NotFound => ...,
        InvalidCString(_) => ...,
        [etc...]

It should also be possible to flatten the match e.g.

match r {
    Ok(r) => ...,
    Err(NotFound) => ...,
    Err(InvalidCString(_)) => ...,
    [etc...]