Class: Elementary::Middleware::RaiseOnStatus

Inherits:
Faraday::Middleware
  • Object
show all
Defined in:
lib/elementary/middleware/raise_on_status.rb

Overview

Raise an exception for certain HTTP response status codes

Examples

Faraday.new do |conn|
  conn.request :raise_on_status
  conn.adapter ...
end

The above example will raise an HttpStatusError if the response contains a code in the range 300 through 600.

You can also pair this with the retry middleware to attempt to recover from intermittent failures…

Faraday.new do |conn|
  conn.request :retry, max: 2, interval: 0.05,
                       interval_randomness: 0.5, backoff_factor: 2
                       exceptions: [Faraday::TimeoutError, SecurityEvents::HttpStatusError]
  conn.request :raise_on_status
  conn.adapter ...
end

This example will do the same as the first, but the exception will be caught by the retry middleware and the request will be executed up to two more times before raising. NOTE: Middleware order matters here!

Constant Summary collapse

DEFAULT_STATUS_ARRAY =
[300..600]
ERROR_HEADER_MSG =
'x-protobuf-error'
ERROR_HEADER_CODE =
'x-protobuf-error-reason'

Instance Method Summary collapse

Constructor Details

#initialize(app) ⇒ RaiseOnStatus

Public: Initialize middleware



66
67
68
69
70
# File 'lib/elementary/middleware/raise_on_status.rb', line 66

def initialize(app)
  super(app)
  status_array ||= DEFAULT_STATUS_ARRAY
  @status_set = status_option_array_to_set(status_array)
end

Instance Method Details

#call(request_env) ⇒ Object



72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
# File 'lib/elementary/middleware/raise_on_status.rb', line 72

def call(request_env)
  begin
    @app.call(request_env).on_complete do |response_env|
      status = response_env[:status]
      if @status_set.include? status
        error_opts = {
            :status_code => status,
            :method => response_env.method.to_s.upcase,
            :url => response_env.url.to_s
        }
        headers = response_env[:response_headers]
        if headers.include?(ERROR_HEADER_CODE) && headers.include?(ERROR_HEADER_MSG)
          error_opts[:header_message] = headers[ERROR_HEADER_MSG]
          error_opts[:header_code] = headers[ERROR_HEADER_CODE]
          raise Elementary::Errors::RPCFailure, error_opts
        else
          raise HttpStatusError, error_opts
        end
      end
    end
  rescue Faraday::ClientError => e
    raise HttpStatusError, :parent_message => e.message
  end
end