Skip to content
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

Add error traits for communication interfaces #296

Merged
merged 7 commits into from
Oct 5, 2021

Conversation

eldruin
Copy link
Member

@eldruin eldruin commented Jul 13, 2021

There has been a lengthy discussion about this in #229.
This implements proposal 3 by @TeXitoi which was the latest for I2C, SPI and Serial interfaces.
See here for the analysis
I included a minimal number of variants for each protocol, mostly borrowed from embedded-error.

This raises the MSRV to Rust 1.40.0 as well in order to mark the ErrorKinds as #[non_exhaustive] so that adding a new variant is not a breaking change.
I am also fine with not marking the ErrorKinds as #[non_exhaustive].

Closes #229

@eldruin eldruin requested a review from a team as a code owner July 13, 2021 20:46
@rust-highfive
Copy link

r? @therealprof

(rust-highfive has picked a reviewer for you, use r? to override)

@eldruin eldruin force-pushed the comm-error-traits branch 2 times, most recently from 5068535 to bb1dbe8 Compare July 13, 2021 21:02
TeXitoi
TeXitoi previously approved these changes Jul 13, 2021
@therealprof
Copy link
Contributor

@eldruin Is this in line with the plans of the Rust error handling project group? Haven't had time to check, just making sure that we're not working contrary to what's coming up in upstream Rust...

@eldruin
Copy link
Member Author

eldruin commented Jul 14, 2021

Good point.
This proposal is simpler than that and only includes the already standard Error::kind() mechanism, without any kind of chaining, which is what the error WG described here.
If we were to offer a mechanism somewhat similar to Error::source, I think we would need to make the errors contain a generic parameter for the source error, which we have already discussed.
Nevertheless, with this proposal users and HALs can continue to create an error chaining mechanism however they like.

The only thing this proposal does is requiring that whatever error type the HAL implementation returns, a mapping to a set of common error variants exists, upon which generic drivers can act.

@ryankurte
Copy link
Contributor

this seems to me like a good synthesis of the work in the related issue! as with @therealprof i wonder how this aligns with the error-handling WG and existing std:error::Error / failure::Fail infrastructure.

it doesn't seem like it'd be useful to enforce those bounds through our API, but, it might be helpful to add (feature-gated) implementations for either std:error::Error or failure::Fail to our ErrorKinds for if/when they're used directly?

@eldruin
Copy link
Member Author

eldruin commented Jul 16, 2021

Hmm, ErrorKinds would not be part of the error chain themselves as I do not understand them as a std::error::Error::source().
Rather, the original HAL-defined error types are the sources and those would form the error chain.
What we would add here is requiring that those errors could be translated into a predefined subset: ErrorKinds, similar to std::io::Error.

If those HAL-defined error types implement std::error::Error, they get failure::Error for free IIUC.

I have implemented core::fmt::Display for the ErrorKinds, though. Which I guess could be useful.

@yodaldevoid
Copy link
Contributor

Hmm, ErrorKinds would not be part of the error chain themselves as I do not understand them as a std::error::Error::source().
Rather, the original HAL-defined error types are the sources and those would form the error chain.
What we would add here is requiring that those errors could be translated into a predefined subset: ErrorKinds, similar to std::io::Error.

I believe there was talk about allowing ErrorKind to directly be as the HAL error type where it fits for a specific HAL. It's fine to explicitly disallow or discourage this use, but if we would still like to support this then I would ask that std::error::Error be conditionally implemented for ErrorKind.

@eldruin
Copy link
Member Author

eldruin commented Aug 5, 2021

HALs can indeed use ErrorKind as their error type if that is enough for them. I have implemented the embedded-hal::<protocol>::Error traits for those in this PR.

A different topic would be implementing std::error::Error for ErrorKind as well. That would be an independent addition but only really useful for linux-embedded-hal or so, which I highly doubt would adopt ErrorKind as its protocol error type.
The main point against it being that std::error::Error requires memory allocation so it is uninteresting for no_std HALs.
Anyway if there would really be interest, we could add this in a future release via an opt-in feature, but I would not hold the merge of this since that would be a hypothetical non-breaking addition.

@yodaldevoid
Copy link
Contributor

This PR is just waiting for a final review and a quick update to update the change-log, correct?

Copy link
Contributor

@dbrgn dbrgn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the proposal, I like it. It's a lightweight approach that provides flexibility for HALs to define their custom error types, while at the same time offering a possibility to map custom errors to a standardized set of error types.

src/errors.rs Outdated Show resolved Hide resolved
src/errors.rs Outdated Show resolved Hide resolved
src/errors.rs Outdated Show resolved Hide resolved
src/errors.rs Outdated Show resolved Hide resolved
@eldruin eldruin force-pushed the comm-error-traits branch 2 times, most recently from ed105ef to f16b10c Compare August 31, 2021 07:39
@Dirbaio
Copy link
Member

Dirbaio commented Aug 31, 2021

+1 to having official "error kinds" that generic drivers can react to. This is sorely needed!

Maybe this PR should enforce that the Error associated types impl the Error trait? The original proposal does so.

@eldruin
Copy link
Member Author

eldruin commented Aug 31, 2021

@Dirbaio @yodaldevoid I missed re-adding the Error trait requirements on the associated types today by mistake as I re-did this PR completely on top of the current master branch. Sorry for the confusion.

@eldruin eldruin force-pushed the comm-error-traits branch 3 times, most recently from 4e8dbb3 to f7ab7b1 Compare August 31, 2021 19:58
Copy link
Member

@Dirbaio Dirbaio left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've commented some bikeshedding on the error enums :)

src/i2c.rs Show resolved Hide resolved
src/i2c.rs Outdated Show resolved Hide resolved
src/spi/mod.rs Outdated Show resolved Hide resolved
src/spi/mod.rs Outdated Show resolved Hide resolved
@therealprof
Copy link
Contributor

Still not too much of a fan of the Other kind and would have preferred an ImplError instead as I've done in embedded-error. Anyway, this PR is fine with me.

@eldruin eldruin mentioned this pull request Sep 1, 2021
@yodaldevoid
Copy link
Contributor

Is this still awaiting further reviews?

src/spi/mod.rs Outdated Show resolved Hide resolved
timokroeger added a commit to timokroeger/embedded-hal that referenced this pull request Oct 4, 2021
Copy link
Contributor

@therealprof therealprof left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@eldruin
Copy link
Member Author

eldruin commented Oct 5, 2021

🎉
bors r=therealprof

@bors bors bot merged commit b72255c into rust-embedded:master Oct 5, 2021
@dbrgn
Copy link
Contributor

dbrgn commented Oct 5, 2021

🎉 thank you @eldruin!

Piroro-hs added a commit to Piroro-hs/embedded-hal that referenced this pull request Oct 8, 2021
bors bot added a commit that referenced this pull request Oct 8, 2021
317: Move #296 changelog entry to unreleased section r=eldruin a=Piroro-hs

Just a small fix for CHANGELOG.md

Co-authored-by: Piroro-hs <Piroro-hs@users.noreply.github.com>
ryankurte pushed a commit to ryankurte/embedded-hal that referenced this pull request Oct 13, 2021
timokroeger added a commit to timokroeger/embedded-hal that referenced this pull request Oct 20, 2021
bors bot added a commit that referenced this pull request Nov 2, 2021
316: I2C NACK error nesting r=therealprof a=yodaldevoid

This idea was first proposed [here](#296 (comment)), but broken out to keep things moving.

This merges `ErrorKind::NoAcknowledgeData` and `ErrorKind::NoAcknowledgeAddress` into one variant with a source field to indicate what the NACK was in response to. Some drivers may not be able to differentiate between NACKs on address or data bytes so they should use `NoAcknowledgeSource::Unknown`.

Feel free to bikeshed names and documentation. I used the most obvious names to me, but naming is one of the hardest problems in programming.

Co-authored-by: Gabriel Smith <ga29smith@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-review Review is incomplete T-hal
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[RFC] Revamp Error types
8 participants