Should NoneError implement the Error trait?


#1

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?


#2

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.


#3

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.


#4

Either way it’s not great:

  • Lack of the Error implementation looks like an inconsistency, and when used with Box<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 in Box<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:

  1. Make NoneError compiled in debug mode display (via fmt::Debug?) the file/line it came from.

  2. If it’s not supposed to implement Error, customize E0277 to suggest using .ok_or("msg")


#5

I rather got the impression that the omission is deliberate


#6

:+1:


#7

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:

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:

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


#8

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.