From 5ccddaafef5d603e1749e69aba55b52a3c15161b Mon Sep 17 00:00:00 2001 From: Clayton Passmore Date: Tue, 12 Sep 2023 11:38:01 -0400 Subject: [PATCH] Add option for omitting request data from Faraday exceptions (#1526) --- docs/middleware/included/raising-errors.md | 27 +++++++++++++++++++++- lib/faraday/response/raise_error.rb | 21 ++++++++++++++--- spec/faraday/response/raise_error_spec.rb | 17 +++++++++++++- 3 files changed, 60 insertions(+), 5 deletions(-) diff --git a/docs/middleware/included/raising-errors.md b/docs/middleware/included/raising-errors.md index ca14f0b4b..2f3214e50 100644 --- a/docs/middleware/included/raising-errors.md +++ b/docs/middleware/included/raising-errors.md @@ -6,7 +6,7 @@ This greatly increases the ease of use of Faraday, as you don't have to check the response status code manually. These errors add to the list of default errors [raised by Faraday](getting-started/errors.md). -All exceptions are initialized providing the response `status`, `headers`, and `body`. +All exceptions are initialized with a hash containing the response `status`, `headers`, and `body`. ```ruby conn = Faraday.new(url: 'http://httpbingo.org') do |faraday| @@ -57,3 +57,28 @@ See [Faraday Errors](getting-started/errors.md) for more information on these. The HTTP response status may be nil due to a malformed HTTP response from the server, or a bug in the underlying HTTP library. This is considered a server error and raised as `Faraday::NilStatusError`, which inherits from `Faraday::ServerError`. + +## Middleware Options + +The behavior of this middleware can be customized with the following options: + +| Option | Default | Description | +|---------------------|---------|-------------| +| **include_request** | true | When true, exceptions are initialized with request information including `method`, `url`, `url_path`, `params`, `headers`, and `body`. | + +### Example Usage + +```ruby +conn = Faraday.new(url: 'http://httpbingo.org') do |faraday| + faraday.response :raise_error, include_request: true +end + +begin + conn.get('/wrong-url') # => Assume this raises a 404 response +rescue Faraday::ResourceNotFound => e + e.response[:status] #=> 404 + e.response[:headers] #=> { ... } + e.response[:body] #=> "..." + e.response[:request][:url_path] #=> "/wrong-url" +end +``` diff --git a/lib/faraday/response/raise_error.rb b/lib/faraday/response/raise_error.rb index 9383d39d0..7d8264eb7 100644 --- a/lib/faraday/response/raise_error.rb +++ b/lib/faraday/response/raise_error.rb @@ -39,11 +39,26 @@ def on_complete(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, + 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.fetch(:include_request, true) + + response.merge( request: { method: env.method, url: env.url, @@ -52,7 +67,7 @@ def response_values(env) headers: env.request_headers, body: env.request_body } - } + ) end def query_params(env) diff --git a/spec/faraday/response/raise_error_spec.rb b/spec/faraday/response/raise_error_spec.rb index 2a4684513..06a7096b4 100644 --- a/spec/faraday/response/raise_error_spec.rb +++ b/spec/faraday/response/raise_error_spec.rb @@ -149,7 +149,7 @@ describe 'request info' do let(:conn) do Faraday.new do |b| - b.response :raise_error + b.response :raise_error, **middleware_options b.adapter :test do |stub| stub.post(url, request_body, request_headers) do [400, { 'X-Reason' => 'because' }, 'keep looking'] @@ -157,6 +157,7 @@ end end end + let(:middleware_options) { {} } let(:request_body) { JSON.generate({ 'item' => 'sth' }) } let(:request_headers) { { 'Authorization' => 'Basic 123' } } let(:url_path) { 'request' } @@ -180,5 +181,19 @@ expect(ex.response[:request][:body]).to eq(request_body) end end + + context 'when the include_request option is set to false' do + let(:middleware_options) { { include_request: false } } + + it 'does not include request info in the exception' do + expect { perform_request }.to raise_error(Faraday::BadRequestError) do |ex| + expect(ex.response.keys).to contain_exactly( + :status, + :headers, + :body + ) + end + end + end end end