Skip to content
Matt Muller edited this page Apr 10, 2024 · 2 revisions

Errors are a collection of classes that represent generic service errors and modeled Smithy error shapes. Error have a 1:1 mapping to Smithy structure shapes modeled with the error trait.

@error("client")
@httpError(422)
structure UnprocessableEntityError {
    @httpPayload
    errors: AttributeErrors
}

Usage

Errors are raised by the client when something goes wrong. The error class is determined based upon the error code returned by the service. Depending on protocol implementation, this could be from a header, a member of the body, or even the HTTP status code. In the @railsJson protocol, the status code is used by default, or it can be configured to come from the x-smithy-rails-error header. Generic errors are returned when no modeled errors matches the error code.

client = HighScoreService::Client.new(endpoint: 'http://127.0.0.1:3000')
# => #<HighScoreService::Client ... >

# Generic error
client.delete_high_score(id: '1')
# raises NotFoundError (HighScoreService::Errors::ApiClientError)

# Modeled error
# Assumes service has a validation of "game" having a length of at least 2
# If validation fails, service is expected to return a status code of 422
client.create_high_score(high_score: { game: 'X', score: 123 })
# raises UnprocessableEntityError (HighScoreService::Errors::UnprocessableEntityError)

Class Hierarchy

Error classes from Hearth and generated SDKs have an inheritance hierarchy so that specific errors can be caught depending on desired granularity. The hierarchy is as follows, from specific to generic:

  1. Any modeled service errors using the @error trait. These errors inherit one of the service's generic errors based upon the status code property of this trait.
  2. The service’s generic errors, such as ApiClientError (4xx), ApiServerError (5xx), or ApiRedirectError (3xx) in HTTP protocols.
  3. The service’s generic ApiError.
  4. Hearth::HTTP::ApiError for HTTP protocols.
  5. Hearth::ApiError for generic errors.
  6. Ruby’s StandardError

Determining Errors

To determine if an HTTP response has an error, the following steps are performed:

  1. Check if the response has an error code that directly maps to a defined error class, and if so, use that error.
  2. Check if the response status code equals the successful status code on the @http trait, and if so, it is not an error.
  3. If the response status code is 2xx, it is not an error.
  4. If the response code is 5xx, then raise a generic ApiServerError.
  5. If the response code is 3xx, then raise a generic ApiRedirectError with the Location header.
  6. Everything else, raise a generic ApiClientError.