I've gone through crates.io github repo. I really like the structure of project itself and currently trying to make use of it in my own project.
In crates.io they have AppError trait.
From handlers they return Box<dyn AppError>. There are From implementations for different kind of errors, but all of them are just boxed. I mean they are raw, not converted to user-friendly wrapper. Is it okay to leave for example database errors as they are and send them straight to client?
I've worked with 3rd party APIs that thought it would be completely fine to just dump a whole stack trace as part of an error response. I personally wouldn't do that and neither does crates.io, as far as I can tell:
impl From<diesel::ConnectionError> for BoxedAppError {
fn from(err: diesel::ConnectionError) -> BoxedAppError {
Box::new(err)
}
}
impl From<DieselError> for BoxedAppError {
fn from(err: DieselError) -> BoxedAppError {
match err {
DieselError::NotFound => not_found(),
e if is_read_only_error(&e) => {
let detail = "crates.io is currently in read-only mode. Please check https://status.crates.io/ for details and try again later.";
custom(StatusCode::SERVICE_UNAVAILABLE, detail)
}
DieselError::DatabaseError(DatabaseErrorKind::ClosedConnection, _) => {
service_unavailable()
}
_ => Box::new(err),
}
}
}
They send some db errors. I guess like duplicate violation, foreign key etc etc.
And here they just Box::new(e) them without any converting and/or formatting
Yes, the error is logged in the middleware but what makes it to the client is just a string Internal Server Error in the body of a status 500 response, according to the IntoResponse implementation of BoxedAppError:
Oh yeah. I see now
I found some examples of using helper functions at the top of error.rs. So am i getting right that only explicitly created errors, with functions like bad_request, account_locked, forbidden etc, will not be Internal server error?
I haven't checked the controllers or the middleware, but that's how I interpret the util::errors module, too. The helper functions rely on CustomApiError, which has a different response body than the generic implementation of AppError implementation for E: Error.