Derive Macro seamless::ApiError

source ·
#[derive(ApiError)]
{
    // Attributes available to this derive:
    #[api_error]
}
Expand description

Use this macro to generate an Into<ApiError> implementation for your custom error type. Your custom error type needs to implement Debug and Display in order to derive ApiError. Display in particular determines what the error message will be. You can then use attribtues to set the status code, and decide on whether the error message will be internal-only or external.

If the error is marked as being internal, the output from the Display impl will be set as the internal_message on the ApiError struct, and by default the external_message field will be set to "Internal server error". You can set the external message to something different by using the external = "some message" attribute.

If the error is marked as being external, the output from the Display impl will be set as the external_message and internal_message on the ApiError.

You can also set a status code, otherwise the error will return with a status code set to 500.

Attributes

Several attributes can be provided to tweak how this works:

  • #[api_error(internal)]: At the top of a struct or on an enum variant, this denotes that the error message is for internal eyes only, and the external message will be set to a sensible default.
  • #[api_error(external = "Foo")]: At the top of a struct of enum variant, this sets the external_message to be “Foo”, so that the Display impl will be set on the internal_message field only (similar to internal, above).
  • #[api_error(code = 401)]: At the top of a struct of enum variant, this sets the status code to be returned in the ApiError struct.

These attributes can be combined.

Example

#[derive(ApiError, Debug)]
#[api_error(internal, code = 401, external = "Whoops!")]
struct MyError;

// We could use something like `thiserror` to generate our `Display` impls:
impl std::fmt::Display for MyError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "A thing has gone wrong")
    }
}

let e: ApiError = MyError.into();
assert_eq!(
    e,
    ApiError {
        code: 401,
        internal_message: "A thing has gone wrong".to_owned(),
        external_message: "Whoops!".to_owned(),
        value: None
    }
);