-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Uniform error handling through ? in handlers and FromDataSimple #857
Comments
When I'm at a real keyboard I can explain further, but here a few highlights:
|
Everything @jebrosen said is exactly on point. Regarding the However,
I don't think this is the case at the moment because returning a In all, we have plans to ameliorate all of the issues you've raised, but all of them are blocked on upstream Rust changes. The |
Thanks for your responses, good to hear that I didn't just miss something obvious!
In my case, it's about sharing the error type between handlers and
I am looking at So I guess the idea is I would do |
I managed to find a satisfactory solution to this issue by defining a
Then you can reuse the |
Yeah, that seem similar to the |
I'm not sure if this is related to this, but dealing with the same issue as the OP, I find a strange behaviour - if I implement so in the following: impl FromDataSimple for KnownIssue {
type Error = DispatcherrError;
fn from_data(req: &Request, data: Data) -> data::Outcome<Self, Self::Error> {
// Ensure content type is json
if req.content_type() != Some(&ContentType::JSON) {
return Outcome::Forward(data);
}
let mut issue_str = String::new();
if let Err(e) = data.open().take(LIMIT).read_to_string(&mut issue_str) {
return Failure((
Status::InternalServerError,
DispatcherrError::InternalServerError(anyhow::anyhow!(e)),
));
}
let issue_to_insert = match serde_json::from_str(&issue_str) {
Ok(issue) => issue,
Err(e) => {
return Failure((
Status::InternalServerError,
DispatcherrError::InternalServerError(e.into()),
))
}
};
Success(issue_to_insert)
}
} If |
Feature Request / Question
I would like to use uniform error handling throughout my handlers and
FromDataSimple
implementations. To this end, I have an error enum:To use this for error handling in route functions, I have a
Responder
implementaion:This means my handlers can return
Result<..., RequestError>
, and?
works just perfectly.However, even with this boilerplate, I still cannot use
?
in aFromDataSimple
implementation. To make that work, I have to also addthen I can do
This generally works, and the errors with the expected body and status code are returned to the user.
However, notice that there are now two
impl
s that need to figure out a status code for an error: theimpl Responder
, and theimpl From
forfrom_data
. This problem occurs because afrom_data
, in case of a failure, needs to return both aStatus
and some error type. Given an error type that implementsResponder
(which I'd assume to be the common case in a Rocket app), that is rather redundant.And this is not enough: to actually get the errors from
from_data
to the user, I also need to write my handlers as follows:And even with this extra boilerplate, error handling in
from_data
is still not as nice as I'd like it to be: For example, calling a function that returnsResult<..., chrono::ParseError>
looks likeI would usually add
impl From<chrono::ParserError> for RequestError
and then doheader.parse()?
, but here I would needimpl From<chrono::ParseError> for Result<rocket::Data, (Status, RequestError)>
and that is rejected by rustc ("impl doesn't use types inside crate").How Rocket could help
Generally I am asking for advice on how to improve the above situation. :D I also feel I am probably not using all these pieces the way they are intended to be used, but I couldn't find a more convenient approach to error handling. The Rocket guide has a chapter about error catchers, but I couldn't find anything on how to set up your error types such that coding the actual functionality is as convenient as possible (aka, maximal use of
?
).Beyond extended documentation, maybe there are things Rocket could do different to help, so I am also asking if you could consider such error handling in the overall Rocket design (in case there's no better way to do this currently). Not having a redundant
Status
indata::Outcome
and instead relying on aResponder
error type would help. And maybe theimpl Try for outcome::Outcome
could be improved to make it work better with custom error types; the fact that it hastype Error = Result<F, E>
means that as a user, I can only compose this with my own conversion functions to a very limited extend.type Error = E
would help, together with removing the redundantStatus
it would mean that I can add my ownimpl From<...> for E
. Or maybe theimpl Try
could add explicit support for doing some conversion before producing theE
, by being generic over someInto<E>
?I am sure things are the way they are in Rocket for a reason, so none of these suggestions may make any sense.
The text was updated successfully, but these errors were encountered: