1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83
|
# frozen_string_literal: true
module Faraday
class Response
# RaiseError is a Faraday middleware that raises exceptions on common HTTP
# client or server error responses.
class RaiseError < Middleware
# rubocop:disable Naming/ConstantName
ClientErrorStatuses = (400...500)
ServerErrorStatuses = (500...600)
ClientErrorStatusesWithCustomExceptions = {
400 => Faraday::BadRequestError,
401 => Faraday::UnauthorizedError,
403 => Faraday::ForbiddenError,
404 => Faraday::ResourceNotFound,
408 => Faraday::RequestTimeoutError,
409 => Faraday::ConflictError,
422 => Faraday::UnprocessableContentError,
429 => Faraday::TooManyRequestsError
}.freeze
# rubocop:enable Naming/ConstantName
DEFAULT_OPTIONS = { include_request: true, allowed_statuses: [] }.freeze
def on_complete(env)
return if Array(options[:allowed_statuses]).include?(env[:status])
case env[:status]
when *ClientErrorStatusesWithCustomExceptions.keys
raise ClientErrorStatusesWithCustomExceptions[env[:status]], response_values(env)
when 407
# mimic the behavior that we get with proxy requests with HTTPS
msg = %(407 "Proxy Authentication Required")
raise Faraday::ProxyAuthError.new(msg, response_values(env))
when ClientErrorStatuses
raise Faraday::ClientError, response_values(env)
when ServerErrorStatuses
raise Faraday::ServerError, response_values(env)
when nil
raise Faraday::NilStatusError, response_values(env)
end
end
# Returns a hash of response data with the following keys:
# - status
# - headers
# - body
# - request
#
# The `request` key is omitted when the middleware is explicitly
# configured with the option `include_request: false`.
def response_values(env)
response = {
status: env.status,
headers: env.response_headers,
body: env.body
}
# Include the request data by default. If the middleware was explicitly
# configured to _not_ include request data, then omit it.
return response unless options[:include_request]
response.merge(
request: {
method: env.method,
url: env.url,
url_path: env.url.path,
params: query_params(env),
headers: env.request_headers,
body: env.request_body
}
)
end
def query_params(env)
env.request.params_encoder ||= Faraday::Utils.default_params_encoder
env.params_encoder.decode(env.url.query)
end
end
end
end
Faraday::Response.register_middleware(raise_error: Faraday::Response::RaiseError)
|