-
Notifications
You must be signed in to change notification settings - Fork 125
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
Async Request Handlers by customizing error response #529
Conversation
Codecov Report
@@ Coverage Diff @@
## master #529 +/- ##
==========================================
- Coverage 84.99% 84.85% -0.14%
==========================================
Files 110 111 +1
Lines 5617 5757 +140
==========================================
+ Hits 4774 4885 +111
- Misses 843 872 +29
Continue to review full report at Codecov.
|
I don't understand why this is neccessary. Looking at your example code let _io_error = Err(std::io::Error::last_os_error())
.map_err_with_customized_response(
state,
|_state| {
// an error occurs, but still sending **OK** to client
(StatusCode::OK, mime::TEXT_PLAIN_UTF_8, "Customized response by the last os error (Intentionally return 200 even error occurs)")
},
)?; Why don't you just write your code like this: let io_result = Err(std::io::Error::last_os_error());
let _result = match io_result {
Ok(result) => result,
Err(_) => {
let resp = create_response(&state, StatusCode::OK, mime::TEXT_PLAIN_UTF_8, "Custom error response");
return (state, resp);
}
}
// do whatever with result to create your non-error response |
Well we can use the '?' shorthand. |
I see what you are trying to acchieve but I don't think this is the way to go. In all of your examples, you did not specify a concrete type for The 4th example (that uses If you believe I'm wrong, please add a test/example for both |
|
Yes, that is exactly what I said. We're supporting both handler styles, owned and borrowed, and |
So is there any way to use '?' shorthand in both cases? By handler design, it seems impossible, can you/someone shed some ideas? |
No, I'm not talking about |
The best solution to this would be using |
Just for curious, |
Well, I'm not an expert in this field and I also have no benchmarks to backup any assumptions. But Btw is there any reason why you prefer using |
Thanks very much, your explanation makes sense. Why I prefer |
Maybe you are mixing your own logic with gotham's logic. Gotham (as of right now) expects the handler to return an error only if it is unable to produce a response, no matter if that is response has a 200, 400 or 500 status code, and that kind of makes sense to me. For your use case, I'd suggest you create some custom error type like #[derive(Debug, Error)]
enum MyError {
#[error("I/O Error: {0}")]
IoError(#[from] std::io::Error),
#[error("{0}")]
Other(String)
}
impl MyError {
fn try_into_response() -> HandlerResult { /* create custom error response */ }
} and then have your handler return some route.get("/foo").to(|state| {
let res = my_handler(&state).map(|resp| Ok(resp)).unwrap_or_else(|err| err.try_into_response());
match res {
Ok(resp) => Ok((state, resp)),
Err(err) => Err((state, err))
}
}); This way you can use the |
Thanks for the very useful tip.
|
Thanks for your thoughts, but I still think that a response with a status code that indicates an error to the http client is still a successful response from gotham's perspective as the handler was able to produce a response. |
OK, thanks. |
/// # customize response for HandlerError
/// ## Why do we need it?
/// We might want to customize different response for different error, eg:
/// * for authorized-user-resource, we might return 403(Forbidden) for an un-logged-in user;
/// * or when some file user requesting is not found, we might return 404;
/// * ...
/// Or we just want to send with content-type: application/json when request is application/json.
/// (In the old, we just send 500 with plain/text for any request if error happens)