I just experimented with using the ?
operator with Option<T>
and was surprised to find that the resulting error wouldn’t convert into Box<Error>
. It’s not that I have a real use case for this – instead of propagating a rather meaningless NoneError
, it would certainly be better to implement a conversion into a custom error type. I was surprised anyway, since currently NoneError
is the only error type in the standard that does not implement the Error
trait. Is this difference intentional?
I don’t recall it being discussed in the RFC or the PR.
Personally, it not existing so people use .ok_or(something)?
in a Result
method feels reasonable.
I certainly agree with @smarnach on this. It is a bit unclear to me as to why it does not implement Error
. It is at least a bit deceiving that it is called NoneError
but does not implement Error
.
Either way it's not great:
-
Lack of the
Error
implementation looks like an inconsistency, and when used withBox<Error>
gives an IMHO unfriendly error message:error[E0277]: the trait bound
std::option::NoneError: std::error::Error
is not satisfied(the message is technically entirely accurate, but the PLT jargon and number of
::
s in there is off-putting for me) -
NoneError
does not contain file/line number that caused it, so when wrapped inBox<Error>
it may become coompletely detached from the place that generated the error, and may be super hard to figure out what caused it in a large application.So pushing users towards adding
.ok_or("msg")
might actually save them some headache later.
So I'd suggest:
-
Make
NoneError
compiled in debug mode display (viafmt::Debug
?) the file/line it came from. -
If it's not supposed to implement
Error
, customize E0277 to suggest using.ok_or("msg")
Hi, everyone.
I have seen a lot of activity around this question, but have not been able to find a clear, succinct explanation as to why NoneError
should not implement the Error
trait.
A few examples:
- “I’m not sure myself”: https://github.com/rust-lang/rust/pull/42526#issuecomment-311065346
- “I rather got the impression that the omission is deliberate”: Should NoneError implement the Error trait?
- Q asked but not answered: https://github.com/rust-lang/rust/pull/42526#pullrequestreview-57652383
- conversations with multiple people on #rust-beginners IRC came to the same conclusions (no clear understanding of the rationale)
The actual reasoning is very unclear (at least to me). Could some kind soul please summarize (or point to a succinct summary of) the reasoning?
Motivation:
- “something I really want”: https://github.com/rust-lang-nursery/failure/issues/59#issuecomment-347512030
- “I scoured the docs and had a bit of a hard time”: https://github.com/rust-lang-nursery/failure/issues/61
Personally, I must use .ok_or(MyError::MyVariant)?
instead of just ?
when I need to convert a None
into an Result::Err
, and it chafes every single time. Either implementing the Error
trait for NoneError
or having a better understanding of why the extra boilerplate should be necessary would be very much appreciated.
-U007D
Personally, I still feel unclear on whether NoneError
should exist at all. I’ve not been especially happy with the setup where the Try
trait makes all ?
types be isomorphic with result, as I wrote about here – it seems to diminish the applicability of Try
significantly to me. The need to define an artificial NoneError
to make Option
fit (or else use ()
, which also feels somewhat artificial to me, but would be more “common”) is sort of a case in point.
This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.