Handle Error
General error handling in Rust applications
Rust's error handling is different from languages such as Java. It does not have a try...catch
. The normal practice is to define a global error handling type at the application level:
use thiserror::Error;
#[derive(Error, Debug)]
pub enum AppError {
#[error("io: `{0}`")]
Io(#[from] io::Error),
#[error("utf8: `{0}`")]
FromUtf8(#[from] FromUtf8Error),
#[error("diesel: `{0}`")]
Diesel(#[from] diesel::result::Error),
...
}
pub type AppResult<T> = Result<T, AppError>;
The thiserror
library is used here, which can easily define your own custom error type and simplify the code. For simple writing, define an AppResult
by the way.
Error handling in Handler
In Salvo, Handler
often encounters various errors, such as: database connection error, file access error, network connection error, etc. For this type of error, the above error handling methods can be used:
#[handler]
async fn home()-> AppResult<()> {
}
Here home
directly returns an AppResult<()>
. However, how to display this error? We need to implement Writer
for the custom error type AppResult
, in this implementation we can decide How to display errors:
#[async_trait]
impl Writer for AppError {
async fn write(mut self, _req: &mut Request, depot: &mut Depot, res: &mut Response) {
res.render(Text::Plain("I'm a error, hahaha!"));
}
}
Error
often contains some sensitive information, under normal circumstances, you don't want to be seen by ordinary users, it is too insecure, and there is no privacy at all. However, if you are a developer or webmaster, you may think It's not the same, you want the error to strip the coat naked and let you see the most real error message.
It can be seen that in the write
method, we can actually get the references of Request
and Depot
, which can easily implement the above operation:
#[async_trait]
impl Writer for AppError {
async fn write(mut self, _req: &mut Request, depot: &mut Depot, res: &mut Response) {
let user = depot.obtain::<User>();
if user.is_admin {
res.render(Text::Plain(e.to_string()));
} else {
res.render(Text::Plain("I'm a error, hahaha!"));
}
}
}
Display of error page
The error page that comes with Salvo is sufficient in most cases, it can display Html, Json or Xml page according to the requested data type. However, in some cases, we still expect to customize the display of the error page .
This can be achieved by custom Catcher
. For a detailed introduction, see the explanation in the Catcher
section.