Here is the code, I am query a MySQL database in a API:
#[get("/api/v2/tags")]
pub async fn get_tags(
db: Data<R2D2Pool<MySqlConnectionManager>>
) -> Result<Json<Vec<Tag>>, GenericError> {
let mut conn: PooledConnection<MySqlConnectionManager> = db.get().unwrap();
let sql_str = "SELECT * FROM table_non_exist".to_string();
let res = conn.query_map( sql_str, |(id, tagname, description)| Tag {
id,
tagname,
description
}).expect("Query failed.");
println!("{:?}", res);
Ok(Json(res))
}
If something wrong happened in the SQL string, such as querying a table that is not existed, the program will panic and crash:
thread 'actix-rt|system:0|arbiter:0' panicked at 'Query failed.: MySqlError { ERROR 1146 (42S02): Table 'myblog.some' doesn't exist }', src/api/tag.rs:30:8
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
I'm wondering what is the best way to handle this panic and return an error in JSON format instead of crashing the app?
The error type of the returned Result
can be anything implementing ResponseError
, so you'd just use Rust's standard Result-based error-handling facilities for this. For example, instead of this, which will panic on error:
let mut conn: PooledConnection<MySqlConnectionManager> = db.get().unwrap();
You could do this (after suitably adjusting the return type from the handler):
let mut conn: PooledConnection<MySqlConnectionManager> = db.get()
.map_err(actix_web::error::ErrorInternalServerError)?;
You'd do the same thing instead of using .expect()
to unwrap the Result
.
If you need to be able to handle different kinds of errors, you need to unify them to a single return type. The simplest approach may be to return Result<_, Box<dyn actix_web::error::ResponseError>>
which has the advantage of conveying any kind of Actix-compatible error, with the downside that the error needs to be put on the heap. (You can always try Result<_, impl actix_web::error::ResponseError>
first to more efficiently handle cases where only one type of error needs to be handled.)
Consider reading the Actix error handling documentation and the actix_web::error
namespace documentation for other functions and types related to error handling.