lib/faraday/conductivity/selective_errors.rb in faraday-conductivity-0.2.1 vs lib/faraday/conductivity/selective_errors.rb in faraday-conductivity-0.3.0

- old
+ new

@@ -1,7 +1,59 @@ module Faraday module Conductivity + + module Error + + attr_accessor :request, :response, :response_time + + def initialize(*) + @request = {} + @response = {} + super + end + + def message + if @wrapped_exception + "#{@wrapped_exception.class}: #{super}" + else + "#{request[:method].to_s.upcase} #{request[:url]} responded with status #{response[:status]}" + end + end + + def inspect + "<#{self.class}> #{message}" + end + + end + + # Use this to raise errors on certain HTTP statuses. These are basically + # the same errors as Faraday raises when you use the "raise_error" + # middleware, but with added fields to better inspect what went wrong. + # + # Examples: + # + # # specify an array + # faraday.response :selective_errors, on: [422,500] + # # or a range: + # faraday.response :selective_errors, on: 500...600 + # # specify errors: + # faraday.response :selective_errors, except: [404,422] + # + # Rescueing the errors: + # + # begin + # do_request + # rescue Faraday::Conductivity::Error => error + # puts error.request[:url] + # puts error.request[:method] + # puts error.request[:body] + # puts error.request[:headers] + # + # puts error.response[:status] + # puts error.response[:body] + # puts error.response[:headers] + # end class SelectiveErrors < Faraday::Middleware ClientErrorStatuses = 400...600 def initialize(app, options = {}) @@ -9,43 +61,51 @@ @on = options.fetch(:on) { ClientErrorStatuses } @except = options.fetch(:except) { [] } end def call(env) - # capture request_body because not accessible afterwards - request_body = env[:body] + # capture request because it will be modified during the request + request = { + :method => env[:method], + :url => env[:url], + :body => env[:body], + :headers => env[:request_headers], + } + + start_time = Time.now + @app.call(env).on_complete do - if should_raise_error?(env[:status]) - raise_error(env, request_body) + + status = env[:status] + + if should_raise_error?(status) + response = { + :status => env[:status], + :body => env[:body], + :headers => env[:response_headers], + } + error = case status + when 404 + Faraday::Error::ResourceNotFound.new(response) + when 407 + # mimic the behavior that we get with proxy requests with HTTPS + Faraday::Error::ConnectionFailed.new(%{407 "Proxy Authentication Required "}) + else + Faraday::Error::ClientError.new(response) + end + error.extend Error + error.response = response + error.request = request + error.response_time = Time.now - start_time + raise error + end + end end def should_raise_error?(status) @on.include?(status) && !@except.include?(status) - end - - def raise_error(env, request_body) - case env[:status] - when 404 - raise Faraday::Error::ResourceNotFound, response_values(env, request_body) - when 407 - # mimic the behavior that we get with proxy requests with HTTPS - raise Faraday::Error::ConnectionFailed, %{407 "Proxy Authentication Required "} - else - raise Faraday::Error::ClientError, response_values(env, request_body) - end - end - - def response_values(env, request_body) - { - :url => env[:url], - :status => env[:status], - :request_body => request_body, - :request_headers => env[:request_headers], - :response_headers => env[:response_headers], - :response_body => env[:body], - } end end end end