Module: VisionAPI::ErrorFactory

Defined in:
lib/vision_api/errors.rb

Overview

Maps the wire's error codes onto the classes above. An unrecognised code still produces an APIError with the code intact, so a new server-side code degrades to "unknown but structured" rather than to a crash.

Constant Summary collapse

BY_CODE =
{
  "invalid_request" => InvalidRequestError,
  "invalid_api_key" => AuthenticationError,
  "unauthorized" => AuthenticationError,
  "forbidden" => PermissionDeniedError,
  "email_not_verified" => PermissionDeniedError,
  "insufficient_credits" => InsufficientCreditsError,
  "task_not_found" => NotFoundError,
  "schema_not_found" => NotFoundError,
  "not_found" => NotFoundError,
  "conflict" => ConflictError,
  "result_expired" => ResultExpiredError,
  "file_too_large" => PayloadTooLargeError,
  "page_limit_exceeded" => PayloadTooLargeError,
  "unsupported_type" => UnsupportedTypeError,
  "pdf_encrypted" => UnprocessableError,
  "invalid_page_selection" => UnprocessableError,
  "invalid_schema" => UnprocessableError,
  "schema_field_conflict" => UnprocessableError,
  "too_many_questions" => UnprocessableError,
  "rate_limited" => RateLimitError,
  "too_many_tasks" => TooManyTasksError,
  "internal_error" => InternalError,
  "provider_error" => ProviderError,
  "sync_timeout" => SyncTimeoutError
}.freeze
BY_STATUS =

Status fallback, for a code this version of the client has not seen yet.

{
  400 => InvalidRequestError,
  401 => AuthenticationError,
  402 => InsufficientCreditsError,
  403 => PermissionDeniedError,
  404 => NotFoundError,
  409 => ConflictError,
  410 => ResultExpiredError,
  413 => PayloadTooLargeError,
  415 => UnsupportedTypeError,
  422 => UnprocessableError,
  429 => RateLimitError,
  500 => InternalError,
  502 => ProviderError,
  504 => SyncTimeoutError
}.freeze

Class Method Summary collapse

Class Method Details

.build(status, body, headers) ⇒ APIError

Returns the right subclass for a failed response.

Returns:

  • (APIError)

    the right subclass for a failed response



211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
# File 'lib/vision_api/errors.rb', line 211

def build(status, body, headers)
  envelope = body.is_a?(Hash) ? body["error"] : nil

  if envelope.is_a?(Hash) && envelope["code"]
    code = envelope["code"].to_s
    message = envelope["message"].to_s
    details = envelope["details"]
  else
    code = "http_#{status}"
    message = if body.is_a?(String) && !body.empty?
                body[0,
                     500]
              else
                "The API returned HTTP #{status} with no error envelope."
              end
    details = nil
  end

  klass = BY_CODE[code] || BY_STATUS[status] || APIError
  klass.new(
    status: status,
    code: code,
    message: message,
    details: details.is_a?(Hash) ? details : nil,
    headers: headers
  )
end