-
-
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
A better Server Error experience #1128
Comments
This was referenced Apr 11, 2017
Allow different error types for incoming and outgoing frame and body errors
tokio-rs/tokio-proto#157
Open
Closed
seanmonstar
added a commit
that referenced
this issue
Apr 6, 2018
**The `Error` is now an opaque struct**, which allows for more variants to be added freely, and the internal representation to change without being breaking changes. For inspecting an `Error`, there are several `is_*` methods to check for certain classes of errors, such as `Error::is_parse()`. The `cause` can also be inspected, like before. This likely seems like a downgrade, but more inspection can be added as needed! The `Error` now knows about more states, which gives much more context around when a certain error occurs. This is also expressed in the description and `fmt` messages. **Most places where a user would provide an error to hyper can now pass any error type** (`E: Into<Box<std::error::Error>>`). This error is passed back in relevant places, and can be useful for logging. This should make it much clearer about what error a user should provide to hyper: any it feels is relevant! Closes #1128 Closes #1130 Closes #1431 Closes #1338 BREAKING CHANGE: `Error` is no longer an enum to pattern match over, or to construct. Code will need to be updated accordingly. For body streams or `Service`s, inference might be unable to determine what error type you mean to return. Starting in Rust 1.26, you could just label that as `!` if you never return an error.
seanmonstar
added a commit
that referenced
this issue
Apr 7, 2018
**The `Error` is now an opaque struct**, which allows for more variants to be added freely, and the internal representation to change without being breaking changes. For inspecting an `Error`, there are several `is_*` methods to check for certain classes of errors, such as `Error::is_parse()`. The `cause` can also be inspected, like before. This likely seems like a downgrade, but more inspection can be added as needed! The `Error` now knows about more states, which gives much more context around when a certain error occurs. This is also expressed in the description and `fmt` messages. **Most places where a user would provide an error to hyper can now pass any error type** (`E: Into<Box<std::error::Error>>`). This error is passed back in relevant places, and can be useful for logging. This should make it much clearer about what error a user should provide to hyper: any it feels is relevant! Closes #1128 Closes #1130 Closes #1431 Closes #1338 BREAKING CHANGE: `Error` is no longer an enum to pattern match over, or to construct. Code will need to be updated accordingly. For body streams or `Service`s, inference might be unable to determine what error type you mean to return. Starting in Rust 1.26, you could just label that as `!` if you never return an error.
seanmonstar
added a commit
that referenced
this issue
Apr 7, 2018
**The `Error` is now an opaque struct**, which allows for more variants to be added freely, and the internal representation to change without being breaking changes. For inspecting an `Error`, there are several `is_*` methods to check for certain classes of errors, such as `Error::is_parse()`. The `cause` can also be inspected, like before. This likely seems like a downgrade, but more inspection can be added as needed! The `Error` now knows about more states, which gives much more context around when a certain error occurs. This is also expressed in the description and `fmt` messages. **Most places where a user would provide an error to hyper can now pass any error type** (`E: Into<Box<std::error::Error>>`). This error is passed back in relevant places, and can be useful for logging. This should make it much clearer about what error a user should provide to hyper: any it feels is relevant! Closes #1128 Closes #1130 Closes #1431 Closes #1338 BREAKING CHANGE: `Error` is no longer an enum to pattern match over, or to construct. Code will need to be updated accordingly. For body streams or `Service`s, inference might be unable to determine what error type you mean to return. Starting in Rust 1.26, you could just label that as `!` if you never return an error.
seanmonstar
added a commit
that referenced
this issue
Apr 7, 2018
**The `Error` is now an opaque struct**, which allows for more variants to be added freely, and the internal representation to change without being breaking changes. For inspecting an `Error`, there are several `is_*` methods to check for certain classes of errors, such as `Error::is_parse()`. The `cause` can also be inspected, like before. This likely seems like a downgrade, but more inspection can be added as needed! The `Error` now knows about more states, which gives much more context around when a certain error occurs. This is also expressed in the description and `fmt` messages. **Most places where a user would provide an error to hyper can now pass any error type** (`E: Into<Box<std::error::Error>>`). This error is passed back in relevant places, and can be useful for logging. This should make it much clearer about what error a user should provide to hyper: any it feels is relevant! Closes #1128 Closes #1130 Closes #1431 Closes #1338 BREAKING CHANGE: `Error` is no longer an enum to pattern match over, or to construct. Code will need to be updated accordingly. For body streams or `Service`s, inference might be unable to determine what error type you mean to return. Starting in Rust 1.26, you could just label that as `!` if you never return an error.
seanmonstar
added a commit
that referenced
this issue
Apr 10, 2018
**The `Error` is now an opaque struct**, which allows for more variants to be added freely, and the internal representation to change without being breaking changes. For inspecting an `Error`, there are several `is_*` methods to check for certain classes of errors, such as `Error::is_parse()`. The `cause` can also be inspected, like before. This likely seems like a downgrade, but more inspection can be added as needed! The `Error` now knows about more states, which gives much more context around when a certain error occurs. This is also expressed in the description and `fmt` messages. **Most places where a user would provide an error to hyper can now pass any error type** (`E: Into<Box<std::error::Error>>`). This error is passed back in relevant places, and can be useful for logging. This should make it much clearer about what error a user should provide to hyper: any it feels is relevant! Closes #1128 Closes #1130 Closes #1431 Closes #1338 BREAKING CHANGE: `Error` is no longer an enum to pattern match over, or to construct. Code will need to be updated accordingly. For body streams or `Service`s, inference might be unable to determine what error type you mean to return. Starting in Rust 1.26, you could just label that as `!` if you never return an error.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
There are 4 error cases on the server side:
Service
'sFuture
resolves to anErr
, meaning that it just could not respond to the RequestStream
has an error while generating more of the outgoing bodyThe current design requires that all 4 of these cases be covered by
hyper::Error
, but that type is not satisfactory for the semantics of each case. This design is currently required because of tokio-proto'sServerProto
only allowing a singleError
type. Relevant tokio issue: tokio-rs/tokio-proto#157Another quirk with the current type is that users must return a
hyper::Error
when they encounter an error during theirService.call
. This causes them to wonder which variant of the currenthyper::Error
they should use, when the real anwer is: none! They should be returning (if it was a server error) a response with a5XX
status code.They are also asked to return a
hyper::Error
in the outgoingStream
, but that is also incorrect. No hyper error occurred! However, they cannot alter to sending a 500 response anymore, so the only valid thing to do is send an error type with the semantics of "something blew up, we cannot respond more, just abort the socket".So, there are 2 error types that would better suit these 4 cases:
Error
: Thehyper::Error
type that comes only from within hyper, and represents when there was an error trying to read and parse incoming HTTP data.Disconnect
: A type that comes only from the user, given to hyper, and represents that the connection should be terminated immediately. Other names could beFatal
,Close
,Abort
...This separation would hopefully give more clarity as to what error a user should be returning, and that in the
Service::Future
type, they shouldn't returning an error at all, since the error name should be ominous enough to point at returning a response instead.There is of course still desire for users to have streams that return error types of
std::io::Error
, such as streaming from aFile
, or evenhyper::Error
, when streaming from a proxied client request, so there should existFrom
implementations for those types.New proposal: #1431
The text was updated successfully, but these errors were encountered: