feat(error): add ErrorClassification trait for triage-friendly Error<Kind> categories#1267
Open
Greg Lamberson (glamberson) wants to merge 1 commit into
Conversation
There was a problem hiding this comment.
Pull request overview
Adds a lightweight, opt-in error triage mechanism by introducing a coarse ErrorCategory enum and an ErrorClassification trait in ironrdp-error, then wiring initial implementations for ironrdp-core’s DecodeErrorKind and EncodeErrorKind (and re-exporting the API from ironrdp-core).
Changes:
- Introduces
ironrdp_error::ErrorCategoryandironrdp_error::ErrorClassification, plusError<Kind>::classify()whenKind: ErrorClassification. - Implements
ErrorClassificationforironrdp_core::DecodeErrorKindandironrdp_core::EncodeErrorKind. - Re-exports
ErrorCategoryandErrorClassificationfromironrdp-coreto keep the common import path for consumers.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| crates/ironrdp-error/src/lib.rs | Defines ErrorCategory, ErrorClassification, and adds Error<Kind>::classify() forwarding to the inner kind. |
| crates/ironrdp-core/src/lib.rs | Re-exports ErrorCategory/ErrorClassification for easier downstream consumption via ironrdp-core. |
| crates/ironrdp-core/src/decode.rs | Classifies DecodeErrorKind structured variants as Protocol, with Other as Unknown. |
| crates/ironrdp-core/src/encode.rs | Classifies EncodeErrorKind structured variants as InternalBug, with Other as Unknown. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
…Kind> categories
Introduces ironrdp_error::{ErrorCategory, ErrorClassification} so consumers
can route errors by coarse category (Protocol, DataCorruption, InternalBug,
Unknown) without inspecting Display strings. Adds a convenience
Error<Kind>::classify() method that is available when Kind: ErrorClassification.
Implements the trait for the two foundational Kind types in ironrdp-core:
DecodeErrorKind classifies all structured variants as Protocol (peer-driven
wire-format failures) and Other as Unknown; EncodeErrorKind classifies all
structured variants as InternalBug (we miscalculated something in our own
serialisation path) and Other as Unknown. ironrdp-core re-exports the trait
and enum so consumers can pull them via the same crate they already use for
DecodeError/EncodeError type aliases.
Primary consumer is the structured-fuzzing oracle code in ironrdp-fuzzing
tracked under Devolutions#1120: categories let an oracle distinguish "decoder
correctly rejected malformed input" from "decoder hit an internal invariant
violation" without inspecting Display strings. The DataCorruption category
is defined now and reserved for the deeper-validation variants that other
*ErrorKind enums in the workspace will adopt in follow-on PRs.
Refs Devolutions#1257, Devolutions#1120.
d48f20e to
c336d58
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Introduces
ironrdp_error::ErrorClassification, a trait that assigns each*ErrorKindvariant a coarse [ErrorCategory] (one ofProtocol,DataCorruption,InternalBug,Unknown). A convenienceError<Kind>::classify()method becomes available onError<Kind>whenKind: ErrorClassification, forwarding to the inner kind.Implements the trait for
DecodeErrorKindandEncodeErrorKindinironrdp-core, and re-exportsErrorCategoryandErrorClassificationfromironrdp-coreso consumers can pull them via the same crate they already use forDecodeError/EncodeError.Closes out the third of the substantive ironrdp-error follow-ons from #1257 (after #1262 location capture, #1263 bail!/ensure! macros, and the position-aware metadata in #1266). Primary consumer is the structured-fuzzing oracle code in #1120.
Why this matters for fuzzing
Structured-fuzz oracles need to distinguish:
Protocol,DataCorruption).InternalBug).Today, an oracle can only differentiate by parsing the
Displaystring of an error, which is fragile and tightly couples oracle code to formatting choices. After this PR, the oracle callserror.classify()and matches on an enum.API
Initial impls in ironrdp-core
OtherDecodeErrorKindProtocol(peer-driven wire-format failures)UnknownEncodeErrorKindInternalBug(we miscalculated something in our own serialisation path)UnknownOtheris intentionallyUnknownbecause it carries a free-formdescription: &'static strand cannot be classified without inspecting that string at compile time.DataCorruptionis defined now but not used byDecodeErrorKind/EncodeErrorKindbecause those enums only carry low-level wire-format variants. It is reserved for the deeper-validation variants that other*ErrorKindenums in the workspace will adopt in follow-on PRs (e.g. session-layer integrity checks, license validation, capability negotiation mismatches).Adoption pattern for other crates
The trait is intentionally not given a default impl returning
Unknown. Per-crate adoption is opt-in: an*ErrorKindthat wants classification implements the trait, andError<Kind>::classify()becomes available onError<Kind>accordingly. Kinds that have not been audited yet simply do not expose the convenience method. This forces classification work to be deliberate rather than silently degrading toUnknownfor unaudited variants.Scope
Strictly additive: no existing
*ErrorKindenum signature changes, no existing constructor changes, noDisplay/Debugchanges. The new trait method is purely opt-in for consumers who need categorisation.This PR limits the per-crate impl work to
ironrdp-core's two foundational kinds. Follow-on PRs may extend the impl to other workspace*ErrorKindtypes as their owners audit them.Diff
crates/ironrdp-error/src/lib.rs(+73):ErrorCategoryenum,ErrorClassificationtrait,Error<Kind>::classify()convenience impl blockcrates/ironrdp-core/src/lib.rs(+2): re-exportsErrorCategoryandErrorClassificationcrates/ironrdp-core/src/decode.rs(+19):ErrorClassificationimpl forDecodeErrorKindcrates/ironrdp-core/src/encode.rs(+20):ErrorClassificationimpl forEncodeErrorKindTotal: 4 files, +114, 0 deletions.
CI
cargo xtask check fmt | lints | locks | typos | testsall pass locally.ironrdp-corebuilds clean under--no-default-features(no_std) and--all-features.Relationship to the other open error PRs
thiserrordependency fromironrdp-pduby hand-rolling Display/Error implsError<Kind>ErrorClassificationtrait + category enum + initial implsAll three are independent and can land in any order.