logins

Attribute Macro handle_error

source
#[handle_error]
Expand description

A procedural macro that exposes internal errors to external errors the consuming applications should handle. It requires that the internal error implements [error_support::ErrorHandling].

Additionally, this procedural macro has side effects, including:

  • It would log the error based on a pre-defined log level. The log level is defined in the [error_support::ErrorHandling] implementation.
  • It would report some errors using an external error reporter, in practice, this is implemented using Sentry in the app.

§Example

use error_support::{handle_error, GetErrorHandling, ErrorHandling};
use std::fmt::Display
#[derive(Debug, thiserror::Error)]
struct Error {}
type Result<T, E = Error> = std::result::Result<T, E>;

impl Display for Error {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(f, "Internal Error!")
    }
}

#[derive(Debug, thiserror::Error)]
struct ExternalError {}

impl Display for ExternalError {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(f, "External Error!")
    }
}

impl GetErrorHandling for Error {
   type ExternalError = ExternalError;

   fn get_error_handling(&self) -> ErrorHandling<Self::ExternalError> {
       ErrorHandling::convert(ExternalError {})
   }
}

// The `handle_error` macro maps from the error supplied in the mandatory argument
// (ie, `Error` in this example) to the error returned by the function (`ExternalError`
// in this example)
#[handle_error(Error)]
fn do_something() -> std::result::Result<String, ExternalError> {
   Err(Error{})
}

// The error here is an `ExternalError`
let _: ExternalError = do_something().unwrap_err();