Skip to content

Commit

Permalink
Merge pull request #1053 from lostisland/raise-error-nil
Browse files Browse the repository at this point in the history
Raise error nil
  • Loading branch information
technoweenie committed Oct 16, 2019
2 parents 708ca5b + c844e4c commit 993a483
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 21 deletions.
50 changes: 29 additions & 21 deletions docs/middleware/response/raise_error.md
Expand Up @@ -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
Expand All @@ -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`
8 changes: 8 additions & 0 deletions lib/faraday/error.rb
Expand Up @@ -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(_exc, 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
Expand Down
2 changes: 2 additions & 0 deletions lib/faraday/response/raise_error.rb
Expand Up @@ -32,6 +32,8 @@ def on_complete(env)
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

Expand Down
7 changes: 7 additions & 0 deletions spec/faraday/response/raise_error_spec.rb
Expand Up @@ -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
Expand Down Expand Up @@ -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')
Expand Down

0 comments on commit 993a483

Please sign in to comment.