I am new to Rust. I am using the sqlite crate and have this:
connection.execute("CREATE TABLE my_table (foo, bar);").unwrap();
If I run this and my_table
already exists, this "raises" an error, as expected:
called `Result::unwrap()` on an `Err` value: Error { code: Some(1), message: Some("table my_table already exists") }
I want to "catch" this specific case, and just ignore it, but keep "raising" the error in any other case. I've been reading the Recoverable Errors with Result in the Rust Book, and there is an example to deal with enum
errors. However, errors in the sqlite crate are structs
instead (doc). Though for an experienced rustacean this may be obvious, I am struggling on how to deal with this. I wrote this piece of code:
match connection.execute("CREATE TABLE my_table (foo, bar);") {
Ok(whatever) => "fine",
Err(error) => {
match error.code {
Some(1) => {
match error.message {
Some(ref msg) => {
if msg == "table my_table already exists" {
"ok"
} else {
panic!("Something happened {:?}", error);
}
}
_ => panic!("Something happened {:?}", error),
}
}
_ => panic!("Something happened {:?}", error),
}
}
};
which seems to work, but it feels to me that is not the way to go, because of how extensive it is and I have many replicated panic!(...)
lines. Is this the way I am supposed to deal with the error? Is there a more idiomatic way?
As @Ry- said, the correct fix is to use CREATE TABLE IF NOT EXISTS
. But to improve your Rust-fu:
match connection.execute("CREATE TABLE my_table (foo, bar);") {
Ok(_) => "fine",
Err(sqlite::Error {
code: Some(1),
message: Some(message),
}) if message == "table my_table already exists" => "ok",
Err(error) => panic!("Something happened: {error:?}"),
}