I’ve run into similar issues developing embedded APIs. It’s commonplace to have devices that are accessed through an on-board interface such as I2C or SPI. In the vast majority of cases, these devices are going to be physically on the same PCB as the MCU, if there is any kind of error accessing the device, it’s an indicator of a hardware problem and the right thing to do is to abort.
However, there are some cases where you don’t want to abort. First, some designs might have pluggable devices, in which case you would want to be able to handle the error. Second, safety critical systems might want to handle some types of device errors explicitly for all sorts of reasons.
The problem is that you don’t want to force all of the first category of users to use a Fallible API, you don’t want to double the number of methods in your API by presenting both choices, and you don’t want to have independent Fallible and Infallible APIs because users might only want to handle a subset of errors.
Rust has evolved solutions for making Fallible APIs easier to use by the caller: first with the try! macro and then with the ? operator. Both of these make it easy to wrap Fallible calls with a default error handler to early return the error back up the call chain.
What would be nice is a language-level way for the API implementer to build a Fallible API and then attach a default Infallible wrapper that could be unwrapped by callers in an analogous way.
For instance, imagine if there was a #[abort_on_error] attribute that you could attach to any function returning a Result which would convert any error result into an abort. Then , provide callers with the opposite of the ? operator (! would be nice if it wasn’t already used to indicate macro usage) to tell the compiler that they want the error result directly instead of using the abort wrapper.
I don’t think there’s any reasonable way to do this in Rust at this moment - you could probably do the first part with a procedural macro, but not the second.
Does anyone know if there are language constructs of this type in any other languages?