From 72b917c8bedfaed5de5588346443d9fd23d0562a Mon Sep 17 00:00:00 2001 From: Michael Herold Date: Fri, 27 Sep 2019 13:40:27 -0500 Subject: [PATCH 1/4] Raise exception on nil status --- lib/faraday/error.rb | 8 ++++++++ lib/faraday/response/raise_error.rb | 2 ++ spec/faraday/response/raise_error_spec.rb | 7 +++++++ 3 files changed, 17 insertions(+) diff --git a/lib/faraday/error.rb b/lib/faraday/error.rb index fd58354db..4d0fc6939 100644 --- a/lib/faraday/error.rb +++ b/lib/faraday/error.rb @@ -80,6 +80,14 @@ def initialize(exc = 'timeout', response = nil) end end + # Raised by Faraday::Response::RaiseError in case of a nil status in response. + class NilStatusError < ServerError + def initialize(response = nil) + message = 'http status could not be derived from the server response' + super(message, response) + end + end + # A unified error for failed connections. class ConnectionFailed < Error end diff --git a/lib/faraday/response/raise_error.rb b/lib/faraday/response/raise_error.rb index 8a380fd40..4ac8b15c7 100644 --- a/lib/faraday/response/raise_error.rb +++ b/lib/faraday/response/raise_error.rb @@ -28,6 +28,8 @@ def on_complete(env) raise Faraday::ConflictError, response_values(env) when 422 raise Faraday::UnprocessableEntityError, response_values(env) + when nil + raise Faraday::NilStatusError, response_values(env) when ClientErrorStatuses raise Faraday::ClientError, response_values(env) when ServerErrorStatuses diff --git a/spec/faraday/response/raise_error_spec.rb b/spec/faraday/response/raise_error_spec.rb index 2f258a5d4..98d890a23 100644 --- a/spec/faraday/response/raise_error_spec.rb +++ b/spec/faraday/response/raise_error_spec.rb @@ -14,6 +14,7 @@ stub.get('conflict') { [409, { 'X-Reason' => 'because' }, 'keep looking'] } stub.get('unprocessable-entity') { [422, { 'X-Reason' => 'because' }, 'keep looking'] } stub.get('4xx') { [499, { 'X-Reason' => 'because' }, 'keep looking'] } + stub.get('nil-status') { [nil, { 'X-Reason' => 'bailout' }, 'fail'] } stub.get('server-error') { [500, { 'X-Error' => 'bailout' }, 'fail'] } end end @@ -72,6 +73,12 @@ end end + it 'raises Faraday::NilStatusError for nil status in response' do + expect { conn.get('nil-status') }.to raise_error(Faraday::NilStatusError) do |ex| + expect(ex.message).to eq('http status could not be derived from the server response') + end + end + it 'raises Faraday::ClientError for other 4xx responses' do expect { conn.get('4xx') }.to raise_error(Faraday::ClientError) do |ex| expect(ex.message).to eq('the server responded with status 499') From 07ddcb93f5e3397ce9e00f594da519673906a052 Mon Sep 17 00:00:00 2001 From: Jonny Date: Fri, 4 Oct 2019 12:34:25 +0100 Subject: [PATCH 2/4] Pass the exception correctly --- lib/faraday/error.rb | 2 +- lib/faraday/response/raise_error.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/faraday/error.rb b/lib/faraday/error.rb index 4d0fc6939..727f60bd7 100644 --- a/lib/faraday/error.rb +++ b/lib/faraday/error.rb @@ -82,7 +82,7 @@ def initialize(exc = 'timeout', response = nil) # Raised by Faraday::Response::RaiseError in case of a nil status in response. class NilStatusError < ServerError - def initialize(response = nil) + def initialize(_exc, response: nil) message = 'http status could not be derived from the server response' super(message, response) end diff --git a/lib/faraday/response/raise_error.rb b/lib/faraday/response/raise_error.rb index 4ac8b15c7..3425d1a60 100644 --- a/lib/faraday/response/raise_error.rb +++ b/lib/faraday/response/raise_error.rb @@ -29,7 +29,7 @@ def on_complete(env) when 422 raise Faraday::UnprocessableEntityError, response_values(env) when nil - raise Faraday::NilStatusError, response_values(env) + raise Faraday::NilStatusError, response: response_values(env) when ClientErrorStatuses raise Faraday::ClientError, response_values(env) when ServerErrorStatuses From 232ec3892e4d55f1e958218206501ecc03879ceb Mon Sep 17 00:00:00 2001 From: rick olson Date: Tue, 15 Oct 2019 13:23:33 -0600 Subject: [PATCH 3/4] the nil status is extremely rare, so check it last --- lib/faraday/response/raise_error.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/faraday/response/raise_error.rb b/lib/faraday/response/raise_error.rb index 3425d1a60..d8ad31879 100644 --- a/lib/faraday/response/raise_error.rb +++ b/lib/faraday/response/raise_error.rb @@ -28,12 +28,12 @@ def on_complete(env) raise Faraday::ConflictError, response_values(env) when 422 raise Faraday::UnprocessableEntityError, response_values(env) - when nil - raise Faraday::NilStatusError, response: 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: response_values(env) end end From f7f91b707766d993a1c45f3717a8bd73fbe3f25f Mon Sep 17 00:00:00 2001 From: rick olson Date: Tue, 15 Oct 2019 13:37:41 -0600 Subject: [PATCH 4/4] raise_error: update docs to mention nil status code --- docs/middleware/response/raise_error.md | 50 ++++++++++++++----------- 1 file changed, 29 insertions(+), 21 deletions(-) diff --git a/docs/middleware/response/raise_error.md b/docs/middleware/response/raise_error.md index 8a46f371e..286d0fbb8 100644 --- a/docs/middleware/response/raise_error.md +++ b/docs/middleware/response/raise_error.md @@ -9,26 +9,9 @@ top_name: Back to Middleware top_link: ./list --- -The `RaiseError` middleware checks the response HTTP code and raises an exception if it is a 4xx or 5xx code. -Specific exceptions are raised based on the HTTP Status code, according to the list below: - -``` -## 4xx HTTP codes -400 => Faraday::BadRequestError -401 => Faraday::UnauthorizedError -403 => Faraday::ForbiddenError -404 => Faraday::ResourceNotFound -407 => Faraday::ProxyAuthError -409 => Faraday::ConflictError -422 => Faraday::UnprocessableEntityError -4xx => Faraday::ClientError (all exceptions above inherit from this one. - -## 5xx HTTP codes -5xx => Faraday::ServerError -``` - -All exceptions classes listed above inherit from `Faraday::Error`, and are initialized providing -the response `status`, `headers` and `body`, available for you to access on rescue: +The `RaiseError` middleware raises a `Faraday::Error` exception if an HTTP +response returns with a 4xx or 5xx status code. All exceptions are initialized +providing the response `status`, `headers`, and `body`. ```ruby begin @@ -37,5 +20,30 @@ rescue Faraday::ResourceNotFound => e e.response[:status] #=> 404 e.response[:headers] #=> { ... } e.response[:body] #=> "..." -end +end ``` + +Specific exceptions are raised based on the HTTP Status code, according to the list below: + +An HTTP status in the 400-499 range typically represents an error +by the client. They raise error classes inheriting from `Faraday::ClientError`. + +* 400 => `Faraday::BadRequestError` +* 401 => `Faraday::UnauthorizedError` +* 403 => `Faraday::ForbiddenError` +* 404 => `Faraday::ResourceNotFound` +* 407 => `Faraday::ProxyAuthError` +* 409 => `Faraday::ConflictError` +* 422 => `Faraday::UnprocessableEntityError` +* 4xx => `Faraday::ClientError` + +An HTTP status in the 500-599 range represents a server error, and raises a +`Faraday::ServerError` exception. + +* 5xx => `Faraday::ServerError` + +The HTTP response status may be nil due to a malformed HTTP response from the +server, or a bug in the underlying HTTP library. It inherits from +`Faraday::ServerError`. + +* nil => `Faraday::NilStatusError`