Skip to main content

ApiError

Derive Macro ApiError 

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

Derive macro for implementing ApiError on enums and structs.

This macro generates an ApiError implementation based on #[api_error(...)] attributes, removing the need to write status_code() and message() by hand.

It is intended to be used together with thiserror::Error.


§Basic usage


#[derive(Debug, thiserror::Error, ApiError)]
enum MyError {
    #[error("Internal failure")]
    #[api_error(status_code = 500, message = "Something went wrong")]
    Failure,
}

§#[api_error] attribute

The #[api_error(...)] attribute may be applied to:

  • enums
  • enum variants
  • structs

§status_code

Sets the HTTP status code returned by the generated implementation.

You can either use the StatusCode enum or a status code literal:

#[derive(Debug, thiserror::Error, ApiError)]
enum MyError {
    #[api_error(status_code = 400)]
    #[error("Got error because of A")]
    ReasonA,

    #[api_error(status_code = StatusCode::CONFLICT)]
    #[error("Got error because of B")]
    ReasonB,
}
assert_eq!(MyError::ReasonB.status_code(), StatusCode::CONFLICT)

If omitted, the status code defaults to 500 Internal Server Error.


§message

Sets the client-facing error message.

#[api_error(message = "Invalid input")]

The message supports formatting using:

  • tuple indices ({0}, {1}, …)
  • named fields ({field})

If omitted, the HTTP status reason phrase is used.


§message(inherit)

Uses the type’s Display implementation (from thiserror) as the API error message.

#[error("Forbidden")]
#[api_error(message(inherit))]
struct Forbidden;

§transparent

Marks the type as a transparent wrapper around another ApiError.

#[derive(Debug, thiserror::Error, ApiError)]
#[error(transparent)]
#[api_error(transparent)]
struct Wrapper(InnerError);

#[derive(Debug, thiserror::Error, ApiError)]
#[error("My inner error")]
struct InnerError;

§Rules

  • transparent must be used alone
  • all API metadata is delegated to the wrapped error

§Multiple attributes

Multiple #[api_error] attributes may be used. When the same field is specified multiple times, the last occurrence wins.

#[api_error(message = "Initial")]
#[api_error(status_code = 202)]
#[api_error(message = "Final")]