Browse files

split out RaiseClientError to it's own middleware

  • Loading branch information...
1 parent eeeb6de commit af3a1f115bc70d45865ebe3d597bd1dcf3803730 @stve committed May 31, 2012
View
34 lib/faraday_middleware.rb
@@ -1,20 +1,22 @@
require 'faraday'
module FaradayMiddleware
- autoload :OAuth, 'faraday_middleware/request/oauth'
- autoload :OAuth2, 'faraday_middleware/request/oauth2'
- autoload :EncodeJson, 'faraday_middleware/request/encode_json'
- autoload :Mashify, 'faraday_middleware/response/mashify'
- autoload :Rashify, 'faraday_middleware/response/rashify'
- autoload :ParseJson, 'faraday_middleware/response/parse_json'
- autoload :ParseXml, 'faraday_middleware/response/parse_xml'
- autoload :ParseMarshal, 'faraday_middleware/response/parse_marshal'
- autoload :ParseYaml, 'faraday_middleware/response/parse_yaml'
- autoload :Caching, 'faraday_middleware/response/caching'
- autoload :Chunked, 'faraday_middleware/response/chunked'
- autoload :RackCompatible, 'faraday_middleware/rack_compatible'
- autoload :FollowRedirects, 'faraday_middleware/response/follow_redirects'
- autoload :Instrumentation, 'faraday_middleware/instrumentation'
+ autoload :OAuth, 'faraday_middleware/request/oauth'
+ autoload :OAuth2, 'faraday_middleware/request/oauth2'
+ autoload :EncodeJson, 'faraday_middleware/request/encode_json'
+ autoload :Mashify, 'faraday_middleware/response/mashify'
+ autoload :Rashify, 'faraday_middleware/response/rashify'
+ autoload :ParseJson, 'faraday_middleware/response/parse_json'
+ autoload :ParseXml, 'faraday_middleware/response/parse_xml'
+ autoload :ParseMarshal, 'faraday_middleware/response/parse_marshal'
+ autoload :ParseYaml, 'faraday_middleware/response/parse_yaml'
+ autoload :Caching, 'faraday_middleware/response/caching'
+ autoload :Chunked, 'faraday_middleware/response/chunked'
+ autoload :RaiseClientError, 'faraday_middleware/response/raise_client_error'
+ autoload :RaiseServerError, 'faraday_middleware/response/raise_server_error'
+ autoload :RackCompatible, 'faraday_middleware/rack_compatible'
+ autoload :FollowRedirects, 'faraday_middleware/response/follow_redirects'
+ autoload :Instrumentation, 'faraday_middleware/instrumentation'
if Faraday.respond_to? :register_middleware
Faraday.register_middleware :request,
@@ -32,7 +34,9 @@ module FaradayMiddleware
:yaml => lambda { ParseYaml },
:caching => lambda { Caching },
:follow_redirects => lambda { FollowRedirects },
- :chunked => lambda { Chunked }
+ :chunked => lambda { Chunked },
+ :raise_client_error => lambda { RaiseClientError },
+ :raise_server_error => lambda { RaiseServerError }
Faraday.register_middleware \
:instrumentation => lambda { Instrumentation }
View
43 lib/faraday_middleware/response/raise_client_error.rb
@@ -0,0 +1,43 @@
+require 'faraday_middleware/response_error_middleware'
+
+module FaradayMiddleware
+ # Public: Raise exceptions on 4xx's from server.
+ class RaiseClientError < FaradayMiddleware::ResponseErrorMiddleware
+
+ # Public: The default exception class raised when encountering an error
+ class ClientError < ServerResponseError; end
+
+ HTTP_STATUS_CODES = {
+ 400 => 'Bad Request',
+ 401 => 'Unauthorized',
+ 402 => 'Payment Required',
+ 403 => 'Forbidden',
+ 404 => 'Not Found',
+ 405 => 'Method Not Allowed',
+ 406 => 'Not Acceptable',
+ 407 => 'Proxy Authentication Required',
+ 408 => 'Request Timeout',
+ 409 => 'Conflict',
+ 410 => 'Gone',
+ 411 => 'Length Required',
+ 412 => 'Precondition Failed',
+ 413 => 'Request Entity Too Large',
+ 414 => 'Request-URI Too Long',
+ 415 => 'Unsupported Media Type',
+ 416 => 'Requested Range Not Satisfiable',
+ 417 => 'Expectation Failed',
+ 418 => "I'm a Teapot",
+ 420 => 'Enhance Your Calm',
+ 422 => 'Unprocessable Entity',
+ 423 => 'Locked',
+ 424 => 'Failed Dependency',
+ 426 => 'Upgrade Required'
+ }
+
+ dependency do
+ self.error_class = ClientError
+ self.status_codes = HTTP_STATUS_CODES
+ end
+
+ end
+end
View
56 lib/faraday_middleware/response/raise_server_error.rb
@@ -1,43 +1,13 @@
-require 'faraday'
+require 'faraday_middleware/response_error_middleware'
module FaradayMiddleware
- # Public: Raise exceptions on 400's and 500's from server.
- class RaiseServerError < Faraday::Response::Middleware
+ # Public: Raise exceptions on 5xx's from server.
+ class RaiseServerError < FaradayMiddleware::ResponseErrorMiddleware
# Public: The default exception class raised when encountering an error
- class ServerError < StandardError
- attr_accessor :env
- def initialize(desc, env)
- @env = env
- super(desc)
- end
- end
+ class ServerError < ServerResponseError; end
HTTP_STATUS_CODES = {
- 400 => 'Bad Request',
- 401 => 'Unauthorized',
- 402 => 'Payment Required',
- 403 => 'Forbidden',
- 404 => 'Not Found',
- 405 => 'Method Not Allowed',
- 406 => 'Not Acceptable',
- 407 => 'Proxy Authentication Required',
- 408 => 'Request Timeout',
- 409 => 'Conflict',
- 410 => 'Gone',
- 411 => 'Length Required',
- 412 => 'Precondition Failed',
- 413 => 'Request Entity Too Large',
- 414 => 'Request-URI Too Long',
- 415 => 'Unsupported Media Type',
- 416 => 'Requested Range Not Satisfiable',
- 417 => 'Expectation Failed',
- 418 => "I'm a Teapot",
- 420 => "Enhance Your Calm",
- 422 => 'Unprocessable Entity',
- 423 => 'Locked',
- 424 => 'Failed Dependency',
- 426 => 'Upgrade Required',
500 => 'Internal Server Error',
501 => 'Not Implemented',
502 => 'Bad Gateway',
@@ -49,25 +19,9 @@ def initialize(desc, env)
510 => 'Not Extended'
}
- attr_accessor :error_class
-
- class << self
- attr_accessor :error_class
- end
-
dependency do
self.error_class = ServerError
- end
-
- def initialize(app = nil, options = {})
- super(app)
- self.error_class = options[:error_class] || self.class.error_class
- end
-
- def on_complete(env)
- return unless HTTP_STATUS_CODES.keys.include?(env[:status].to_i)
-
- raise error_class.new("#{env[:status]} #{HTTP_STATUS_CODES[env[:status].to_i]}", env)
+ self.status_codes = HTTP_STATUS_CODES
end
end
View
36 lib/faraday_middleware/response_error_middleware.rb
@@ -0,0 +1,36 @@
+require 'faraday'
+
+module FaradayMiddleware
+ # Public: Base class for handling error responses from server.
+ class ResponseErrorMiddleware < Faraday::Response::Middleware
+
+ # Base class that is extended for use by the RaiseServerError
+ # and RaiseClientError middlewares
+ class ServerResponseError < StandardError
+ attr_accessor :env
+ def initialize(message, env)
+ @env = env
+ super(message)
+ end
+ end
+
+ attr_accessor :error_class, :status_codes
+
+ class << self
+ attr_accessor :error_class, :status_codes
+ end
+
+ def initialize(app = nil, options = {})
+ super(app)
+ self.error_class = options[:error_class] || self.class.error_class
+ self.status_codes = self.class.status_codes
+ end
+
+ def on_complete(env)
+ return unless status_codes.keys.include?(env[:status].to_i)
+
+ raise error_class.new("#{env[:status]} #{status_codes[env[:status].to_i]}", env)
+ end
+
+ end
+end
View
64 spec/raise_client_error_spec.rb
@@ -0,0 +1,64 @@
+require 'helper'
+require 'faraday_middleware/response/raise_client_error'
+
+describe FaradayMiddleware::RaiseClientError, :type => :response do
+ context 'during configuration' do
+ it 'should allow for a custom Mash class to be set' do
+ described_class.should respond_to(:error_class)
+ described_class.should respond_to(:error_class=)
+ end
+ end
+
+ context 'when used' do
+ before(:each) { described_class.error_class = FaradayMiddleware::RaiseClientError::ClientError }
+ let(:raise_server_error) { described_class.new }
+
+ FaradayMiddleware::RaiseClientError::HTTP_STATUS_CODES.each do |response_code, message|
+
+ it "raises an exception when server's response code is #{response_code}" do
+ lambda {
+ raise_server_error.on_complete(:status => response_code)
+ }.should raise_error(described_class.error_class)
+ end
+
+ end
+
+ it 'should allow for use of custom Error subclasses at the class level' do
+ class SomeRandomClientError < FaradayMiddleware::RaiseClientError::ClientError; end
+ described_class.error_class = SomeRandomClientError
+
+ lambda {
+ raise_server_error.on_complete(:status => '401')
+ }.should raise_error(SomeRandomClientError)
+ end
+
+ it 'should allow for use of custom Error subclasses at the instance level' do
+ class SomeRandomClientError < FaradayMiddleware::RaiseClientError::ClientError; end
+ raise_server_error = described_class.new(nil, :error_class => SomeRandomClientError)
+
+ lambda {
+ raise_server_error.on_complete(:status => '401')
+ }.should raise_error(SomeRandomClientError)
+ end
+ end
+
+ context 'integration test' do
+ let(:stubs) { Faraday::Adapter::Test::Stubs.new }
+ let(:connection) do
+ Faraday::Connection.new do |builder|
+ builder.adapter :test, stubs
+ builder.use described_class
+ end
+ end
+
+ it 'should raise exceptions on server errors' do
+ stubs.get('/error') {
+ [401, {}, '']
+ }
+
+ lambda {
+ connection.get('/error')
+ }.should raise_error(FaradayMiddleware::RaiseClientError::ClientError)
+ end
+ end
+end
View
10 spec/raise_server_error_spec.rb
@@ -24,21 +24,21 @@
end
it 'should allow for use of custom Error subclasses at the class level' do
- class SomeRandomError < FaradayMiddleware::RaiseServerError::ServerError; end
- described_class.error_class = SomeRandomError
+ class SomeRandomServerError < FaradayMiddleware::RaiseServerError::ServerError; end
+ described_class.error_class = SomeRandomServerError
lambda {
raise_server_error.on_complete(:status => '500')
- }.should raise_error(SomeRandomError)
+ }.should raise_error(SomeRandomServerError)
end
it 'should allow for use of custom Error subclasses at the instance level' do
class SomeRandomError < FaradayMiddleware::RaiseServerError::ServerError; end
- raise_server_error = described_class.new(nil, :error_class => SomeRandomError)
+ raise_server_error = described_class.new(nil, :error_class => SomeRandomServerError)
lambda {
raise_server_error.on_complete(:status => '500')
- }.should raise_error(SomeRandomError)
+ }.should raise_error(SomeRandomServerError)
end
end

0 comments on commit af3a1f1

Please sign in to comment.