Skip to content

[Task] Refactor errors to avoid delegating Display to the source #1017

Open
@olivereanderson

Description

@olivereanderson

Description

Currently the errors of the IOTA Identity framework do not follow the following recommendation from the Rust error handling working group :

An error type with a source error should either return that error via source or include that source's error message in its own Display output, but never both.

Not following this recommendation leads to duplicate error messages when printing the error along with its causes (using for instance the popular error handling crate anyhow or the upcoming Report type). See the What the error handling project group is working towards blog post for more details.

Example of somewhere where the recommendation is not followed:

#[derive(Debug, thiserror::Error, strum::IntoStaticStr)]
pub enum identity_did::Error {
// .. 
  #[error("{0}")]
  InvalidDID(#[from] crate::did::DIDError), 
// .. 
}

Note that the #[from] annotation also means that Error::source is delegated to the wrapped error crate::did::DIDError whenever the variant InvalidDID is matched.

Now this code:

use identity_did::{Error, did::DIDError}; 

fn main() -> anyhow::Result<()> {
    let err = Error::InvalidDID(DIDError::Other("DID length exceeds the current maximum"));
    Err(err)?;
    Ok(())
}

produces the following output:

Error: DID length exceeds the current maximum

Caused by:
    DID length exceeds the current maximum

In other words the error message is duplicated.

If we instead had defined the variant as follows:

  #[error("invalid DID handling")]
  InvalidDID(#[from] crate::did::DIDError),

the output would then be

Error: invalid DID handling

Caused by:
    DID length exceeds the current maximum

which does not duplicate the message in "Caused by".

Motivation

This is a Subtask of #534. Fixing this issue would unlock the possibility to explore using anyhow in the Wasm bindings to conveniently produce better error messages there.

Metadata

Metadata

Assignees

No one assigned

    Labels

    ChoreTedious, typically non-functional changeRustRelated to the core Rust code. Becomes part of the Rust changelog.

    Type

    No type

    Projects

    Status

    Product Backlog

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions