Skip to content

Instantly share code, notes, and snippets.

@qsona
Last active March 30, 2020 18:56
Show Gist options
  • Save qsona/fdb962538f84e8b7ca4249521a08f6ac to your computer and use it in GitHub Desktop.
Save qsona/fdb962538f84e8b7ca4249521a08f6ac to your computer and use it in GitHub Desktop.
Faraday MyRaiseError middleware
# A patch for faraday raise_error middleware for my usecase
# faraday: https://github.com/lostisland/faraday
class Connection
def self.foo_service
Thread.current[:foo_connection] ||= Faraday.new(Rails.application.config.x.foo_service_url) do |conn|
conn.request :json
conn.response :my_raise_error # See below comment
conn.response :json, :content_type => /\bjson$/
conn.adapter :net_http
end
end
# Use our original MyRaiseError middleware which is basically same with Faraday::Response::RaiseError middleware
# and Error classes, which is the subset of Faraday::Error family
# See:
# https://github.com/lostisland/faraday/blob/master/lib/faraday/response/raise_error.rb
# https://github.com/lostisland/faraday/blob/master/lib/faraday/error.rb
# https://github.com/lostisland/faraday/pull/1135
class MyRaiseError < Faraday::Response::Middleware
ClientErrorStatuses = (400...500).freeze
ServerErrorStatuses = (500...600).freeze
def on_complete(env)
case env[:status]
when ClientErrorStatuses
raise ClientError.new(response: env.response)
when ServerErrorStatuses
raise ServerError.new(response: env.response)
when nil
raise Error.new(response: env.response)
end
end
end
Faraday::Response.register_middleware(my_raise_error: MyRaiseError)
class Error < StandardError
attr_reader :response, :wrapped_exception
# @qsona: changed this signature from the original one
# See: https://github.com/lostisland/faraday/pull/1135
def initialize(exc = nil, response: nil)
@wrapped_exception = nil unless defined?(@wrapped_exception)
@response = response
super(exc_and_msg!(exc))
end
def backtrace
if @wrapped_exception
@wrapped_exception.backtrace
else
super
end
end
def inspect
inner = +''
inner << " wrapped=#{@wrapped_exception.inspect}" if @wrapped_exception
inner << " response=#{@response.to_hash.inspect}" if @response
inner << " #{super}" if inner.empty?
%(#<#{self.class}#{inner}>)
end
protected
# exc - Either an Exception, or a string message.
# @qsona: changed this signature from the original one
def exc_and_msg!(exc)
if @wrapped_exception.nil?
@wrapped_exception, msg = exc_and_msg(exc)
return msg
end
exc.to_s
end
# @qsona: changed this signature from the original one
def exc_and_msg(exc)
return [exc, exc.message] if exc.respond_to?(:backtrace)
[nil, exc.to_s]
end
end
# Faraday client error class. Represents 4xx status responses.
class ClientError < Error
end
# Faraday server error class. Represents 5xx status responses.
class ServerError < Error
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment