Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add new error classes #841

Merged
merged 2 commits into from
Jan 4, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions UPGRADING.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,19 @@
## Faraday 1.0

### Errors
* Removes sub-class constants definition from `Faraday::Error`. A sub-class (e.g. `ClientError`) was previously accessible
either through the `Faraday` module (e.g. `Faraday::ClientError`) or through the `Faraday::Error` class (e.g. `Faraday::Error::ClientError`).
The latter is no longer available and the former should be used instead, so check your `rescue`s.
* Introduces a new `Faraday::ServerError` (5xx status codes) alongside the existing `Faraday::ClientError` (4xx status codes).
Please note `Faraday::ClientError` was previously used for both.
* Introduces new Errors that describe the most common REST status codes:
* Faraday::BadRequestError (400)
* Faraday::UnauthorizedError (401)
* Faraday::ForbiddenError (403)
* Faraday::ProxyAuthError (407). Please note this raised a `Faraday::ConnectionFailed` before.
* Faraday::UnprocessableEntityError (422)

### Others
* Dropped support for jruby and Rubinius.
* Officially supports Ruby 2.3+
* In order to specify the adapter you now MUST use the `#adapter` method on the connection builder. If you don't do so and your adapter inherits from `Faraday::Adapter` then Faraday will raise an exception. Otherwise, Faraday will automatically push the default adapter at the end of the stack causing your request to be executed twice.
Expand Down Expand Up @@ -27,3 +41,4 @@ conn = Faraday.new(...) do |f|
f.adapter AnyAdapter
end
```

14 changes: 7 additions & 7 deletions lib/faraday/adapter/em_http.rb
Original file line number Diff line number Diff line change
Expand Up @@ -131,9 +131,9 @@ def perform_request(env)
end
rescue EventMachine::Connectify::CONNECTError => err
if err.message.include?("Proxy Authentication Required")
raise Error::ConnectionFailed, %{407 "Proxy Authentication Required "}
raise Faraday::ConnectionFailed, %{407 "Proxy Authentication Required "}
else
raise Error::ConnectionFailed, err
raise Faraday::ConnectionFailed, err
end
rescue => err
if defined?(OpenSSL) && OpenSSL::SSL::SSLError === err
Expand Down Expand Up @@ -170,15 +170,15 @@ def error_message(client)
end

def raise_error(msg)
errklass = Faraday::Error::ClientError
errklass = Faraday::ClientError
if msg == Errno::ETIMEDOUT
errklass = Faraday::Error::TimeoutError
errklass = Faraday::TimeoutError
msg = "request timed out"
elsif msg == Errno::ECONNREFUSED
errklass = Faraday::Error::ConnectionFailed
errklass = Faraday::ConnectionFailed
msg = "connection refused"
elsif msg == "connection closed by server"
errklass = Faraday::Error::ConnectionFailed
errklass = Faraday::ConnectionFailed
end
raise errklass, msg
end
Expand Down Expand Up @@ -226,7 +226,7 @@ def run
end
end
if @errors.size > 0
raise Faraday::Error::ClientError, @errors.first || "connection failed"
raise Faraday::ClientError, @errors.first || "connection failed"
end
end
ensure
Expand Down
10 changes: 5 additions & 5 deletions lib/faraday/adapter/em_synchrony.rb
Original file line number Diff line number Diff line change
Expand Up @@ -76,18 +76,18 @@ def call(env)

@app.call env
rescue Errno::ECONNREFUSED
raise Error::ConnectionFailed, $!
raise Faraday::ConnectionFailed, $!
rescue EventMachine::Connectify::CONNECTError => err
if err.message.include?("Proxy Authentication Required")
raise Error::ConnectionFailed, %{407 "Proxy Authentication Required "}
raise Faraday::ConnectionFailed, %{407 "Proxy Authentication Required "}
else
raise Error::ConnectionFailed, err
raise Faraday::ConnectionFailed, err
end
rescue Errno::ETIMEDOUT => err
raise Error::TimeoutError, err
raise Faraday::TimeoutError, err
rescue RuntimeError => err
if err.message == "connection closed by server"
raise Error::ConnectionFailed, err
raise Faraday::ConnectionFailed, err
else
raise
end
Expand Down
6 changes: 3 additions & 3 deletions lib/faraday/adapter/excon.rb
Original file line number Diff line number Diff line change
Expand Up @@ -64,14 +64,14 @@ def call(env)
@app.call env
rescue ::Excon::Errors::SocketError => err
if err.message =~ /\btimeout\b/
raise Error::TimeoutError, err
raise Faraday::TimeoutError, err
elsif err.message =~ /\bcertificate\b/
raise Faraday::SSLError, err
else
raise Error::ConnectionFailed, err
raise Faraday::ConnectionFailed, err
end
rescue ::Excon::Errors::Timeout => err
raise Error::TimeoutError, err
raise Faraday::TimeoutError, err
end

# @return [Excon]
Expand Down
8 changes: 4 additions & 4 deletions lib/faraday/adapter/httpclient.rb
Original file line number Diff line number Diff line change
Expand Up @@ -49,15 +49,15 @@ def call(env)

@app.call env
rescue ::HTTPClient::TimeoutError, Errno::ETIMEDOUT
raise Faraday::Error::TimeoutError, $!
raise Faraday::TimeoutError, $!
rescue ::HTTPClient::BadResponseError => err
if err.message.include?('status 407')
raise Faraday::Error::ConnectionFailed, %{407 "Proxy Authentication Required "}
raise Faraday::ConnectionFailed, %{407 "Proxy Authentication Required "}
else
raise Faraday::Error::ClientError, $!
raise Faraday::ClientError, $!
end
rescue Errno::ECONNREFUSED, IOError, SocketError
raise Faraday::Error::ConnectionFailed, $!
raise Faraday::ConnectionFailed, $!
rescue => err
if defined?(OpenSSL) && OpenSSL::SSL::SSLError === err
raise Faraday::SSLError, err
Expand Down
4 changes: 2 additions & 2 deletions lib/faraday/adapter/net_http.rb
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ def call(env)
if defined?(OpenSSL) && OpenSSL::SSL::SSLError === err
raise Faraday::SSLError, err
else
raise Error::ConnectionFailed, err
raise Faraday::ConnectionFailed, err
end
end

Expand All @@ -59,7 +59,7 @@ def call(env)

@app.call env
rescue Timeout::Error, Errno::ETIMEDOUT => err
raise Faraday::Error::TimeoutError, err
raise Faraday::TimeoutError, err
end

private
Expand Down
6 changes: 3 additions & 3 deletions lib/faraday/adapter/net_http_persistent.rb
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,12 @@ def proxy_uri(env)
def perform_request(http, env)
http.request env[:url], create_request(env)
rescue Errno::ETIMEDOUT => error
raise Faraday::Error::TimeoutError, error
raise Faraday::TimeoutError, error
rescue Net::HTTP::Persistent::Error => error
if error.message.include? 'Timeout'
raise Faraday::Error::TimeoutError, error
raise Faraday::TimeoutError, error
elsif error.message.include? 'connection refused'
raise Faraday::Error::ConnectionFailed, error
raise Faraday::ConnectionFailed, error
else
raise
end
Expand Down
10 changes: 5 additions & 5 deletions lib/faraday/adapter/patron.rb
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ def call(env)
data = env[:body] ? env[:body].to_s : nil
session.request(env[:method], env[:url].to_s, env[:request_headers], :data => data)
rescue Errno::ECONNREFUSED, ::Patron::ConnectionFailed
raise Error::ConnectionFailed, $!
raise Faraday::ConnectionFailed, $!
end

if (req = env[:request]).stream_response?
Expand All @@ -44,15 +44,15 @@ def call(env)
@app.call env
rescue ::Patron::TimeoutError => err
if connection_timed_out_message?(err.message)
raise Faraday::Error::ConnectionFailed, err
raise Faraday::ConnectionFailed, err
else
raise Faraday::Error::TimeoutError, err
raise Faraday::TimeoutError, err
end
rescue ::Patron::Error => err
if err.message.include?("code 407")
raise Error::ConnectionFailed, %{407 "Proxy Authentication Required "}
raise Faraday::ConnectionFailed, %{407 "Proxy Authentication Required "}
else
raise Error::ConnectionFailed, err
raise Faraday::ConnectionFailed, err
end
end

Expand Down
2 changes: 1 addition & 1 deletion lib/faraday/adapter/rack.rb
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ def call(env)

timeout = env[:request][:timeout] || env[:request][:open_timeout]
response = if timeout
Timer.timeout(timeout, Faraday::Error::TimeoutError) { execute_request(env, rack_env) }
Timer.timeout(timeout, Faraday::TimeoutError) { execute_request(env, rack_env) }
else
execute_request(env, rack_env)
end
Expand Down
63 changes: 40 additions & 23 deletions lib/faraday/error.rb
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
module Faraday
# Faraday error base class.
class Error < StandardError;
end

# Faraday client error class.
class ClientError < Error
class Error < StandardError
attr_reader :response, :wrapped_exception

def initialize(ex, response = nil)
Expand Down Expand Up @@ -45,39 +41,60 @@ def inspect
end
end

# A unified client error for failed connections.
class ConnectionFailed < ClientError;
# Faraday client error class. Represents 4xx status responses.
class ClientError < Error
end

# A 404 error used in the RaiseError middleware
#
# @see Faraday::Response::RaiseError
class ResourceNotFound < ClientError;
# Raised by Faraday::Response::RaiseError in case of a 400 response.
class BadRequestError < ClientError
end

# Raised by FaradayMiddleware::ResponseMiddleware
class ParsingError < ClientError;
# Raised by Faraday::Response::RaiseError in case of a 401 response.
class UnauthorizedError < ClientError
end

# Raised by Faraday::Response::RaiseError in case of a 403 response.
class ForbiddenError < ClientError
end

# Raised by Faraday::Response::RaiseError in case of a 404 response.
class ResourceNotFound < ClientError
end

# Raised by Faraday::Response::RaiseError in case of a 407 response.
class ProxyAuthError < ClientError
end

# Raised by Faraday::Response::RaiseError in case of a 422 response.
class UnprocessableEntityError < ClientError
end

# Faraday server error class. Represents 5xx status responses.
class ServerError < Error
end

# A unified client error for timeouts.
class TimeoutError < ClientError
def initialize(ex = nil)
super(ex || "timeout")
class TimeoutError < ServerError
def initialize(ex = 'timeout', response = nil)
super(ex, response)
end
end

# A unified error for failed connections.
class ConnectionFailed < Error
end

# A unified client error for SSL errors.
class SSLError < ClientError
class SSLError < Error
end

# Raised by FaradayMiddleware::ResponseMiddleware
class ParsingError < Error
end

# Exception used to control the Retry middleware.
#
# @see Faraday::Request::Retry
class RetriableResponse < ClientError;
end

[:ClientError, :ConnectionFailed, :ResourceNotFound,
:ParsingError, :TimeoutError, :SSLError, :RetriableResponse].each do |const|
Error.const_set(const, Faraday.const_get(const))
class RetriableResponse < Error
end
end
8 changes: 4 additions & 4 deletions lib/faraday/request/retry.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ module Faraday
# interval that is random between 0.1 and 0.15.
class Request::Retry < Faraday::Middleware

DEFAULT_EXCEPTIONS = [Errno::ETIMEDOUT, 'Timeout::Error', Error::TimeoutError, Faraday::Error::RetriableResponse].freeze
DEFAULT_EXCEPTIONS = [Errno::ETIMEDOUT, 'Timeout::Error', Faraday::TimeoutError, Faraday::RetriableResponse].freeze
IDEMPOTENT_METHODS = [:delete, :get, :head, :options, :put]

class Options < Faraday::Options.new(:max, :interval, :max_interval, :interval_randomness,
Expand Down Expand Up @@ -90,7 +90,7 @@ def retry_statuses
# @option options [Integer] :backoff_factor (1) The amount to multiple each successive retry's
# interval amount by in order to provide backoff
# @option options [Array] :exceptions ([Errno::ETIMEDOUT, 'Timeout::Error',
# Error::TimeoutError, Faraday::Error::RetriableResponse]) The list of
# Faraday::TimeoutError, Faraday::RetriableResponse]) The list of
# exceptions to handle. Exceptions can be given as Class, Module, or String.
# @option options [Array] :methods (the idempotent HTTP methods in IDEMPOTENT_METHODS) A list of
# HTTP methods to retry without calling retry_if. Pass
Expand Down Expand Up @@ -124,7 +124,7 @@ def call(env)
begin
env[:body] = request_body # after failure env[:body] is set to the response body
@app.call(env).tap do |resp|
raise Faraday::Error::RetriableResponse.new(nil, resp) if @options.retry_statuses.include?(resp.status)
raise Faraday::RetriableResponse.new(nil, resp) if @options.retry_statuses.include?(resp.status)
end
rescue @errmatch => exception
if retries > 0 && retry_request?(env, exception)
Expand All @@ -137,7 +137,7 @@ def call(env)
end
end

if exception.is_a?(Faraday::Error::RetriableResponse)
if exception.is_a?(Faraday::RetriableResponse)
exception.response
else
raise
Expand Down
19 changes: 15 additions & 4 deletions lib/faraday/response/raise_error.rb
Original file line number Diff line number Diff line change
@@ -1,16 +1,27 @@
module Faraday
class Response::RaiseError < Response::Middleware
ClientErrorStatuses = 400...600
ClientErrorStatuses = 400...500
ServerErrorStatuses = 500...600

def on_complete(env)
case env[:status]
when 400
raise Faraday::BadRequestError, response_values(env)
when 401
raise Faraday::UnauthorizedError, response_values(env)
when 403
raise Faraday::ForbiddenError, response_values(env)
when 404
raise Faraday::Error::ResourceNotFound, response_values(env)
raise Faraday::ResourceNotFound, response_values(env)
when 407
# mimic the behavior that we get with proxy requests with HTTPS
raise Faraday::Error::ConnectionFailed, %{407 "Proxy Authentication Required "}
raise Faraday::ProxyAuthError.new(%{407 "Proxy Authentication Required"}, response_values(env))
when 422
raise Faraday::UnprocessableEntityError, response_values(env)
when ClientErrorStatuses
raise Faraday::Error::ClientError, response_values(env)
raise Faraday::ClientError, response_values(env)
when ServerErrorStatuses
raise Faraday::ServerError, response_values(env)
end
end

Expand Down
2 changes: 1 addition & 1 deletion spec/faraday/adapter/typhoeus_spec.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
RSpec.describe Faraday::Adapter::Typhoeus do
features :body_on_get, :parallel

it_behaves_like 'an adapter'
it_behaves_like 'an adapter', skip: true
end
Loading