Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Provide wrappers for the errors that can be raised from a request.
- Loading branch information
Showing
4 changed files
with
131 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
require 'net/http' | ||
|
||
module REST | ||
# This constant can be used to rescue any of the known `Timeout`, `Connection`, and `Protocol` | ||
# error classes. | ||
# | ||
# For instance, to rescue _any_ type of error that could be raise while making a request: | ||
# | ||
# begin | ||
# REST.get('http://example.com/pigeons/12') | ||
# rescue REST::Error => e | ||
# p e # => Timeout::Error | ||
# end | ||
# | ||
# If you want to rescue only `Timeout` related error classes, however, you can limit the scope: | ||
# | ||
# begin | ||
# REST.get('http://example.com/pigeons/12') | ||
# rescue REST::Error::Timeout => e | ||
# p e # => Timeout::Error | ||
# end | ||
module Error | ||
# This constant can be used to rescue only the known `Timeout` error classes. | ||
module Timeout | ||
def self.class_names | ||
%w( | ||
Errno::ETIMEDOUT | ||
Timeout::Error | ||
Net::OpenTimeout | ||
Net::ReadTimeout | ||
) | ||
end | ||
end | ||
|
||
# This constant can be used to rescue only the known `Connection` error classes. | ||
module Connection | ||
def self.class_names | ||
%w( | ||
EOFError | ||
Errno::ECONNABORTED | ||
Errno::ECONNREFUSED | ||
Errno::ECONNRESET | ||
Errno::EHOSTUNREACH | ||
Errno::EINVAL | ||
Errno::ENETUNREACH | ||
SocketError | ||
OpenSSL::SSL::SSLError | ||
) | ||
end | ||
end | ||
|
||
# This constant can be used to rescue only the known `Protocol` error classes. | ||
module Protocol | ||
def self.class_names | ||
%w( | ||
Net::HTTPBadResponse | ||
Net::HTTPHeaderSyntaxError | ||
Net::ProtocolError | ||
Zlib::GzipFile::Error | ||
) | ||
end | ||
end | ||
|
||
private | ||
|
||
[Timeout, Connection, Protocol].each do |mod| | ||
mod.send(:include, Error) | ||
|
||
# Collect all the error classes that exist at runtime. | ||
def mod.classes | ||
class_names.map do |name| | ||
begin | ||
# MRI < 2 does not support full constant paths for `Object.const_get`. | ||
name.split('::').inject(Object) do |current, const| | ||
current.const_get(const) | ||
end | ||
rescue NameError | ||
nil | ||
end | ||
end.compact | ||
end | ||
|
||
# Include the `mod` into the classes. | ||
def mod.extend_classes! | ||
classes.each { |klass| klass.send(:include, self) } | ||
end | ||
|
||
mod.extend_classes! | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
require File.expand_path('../helper', __FILE__) | ||
|
||
require 'openssl' | ||
REST::Error::Connection.extend_classes! | ||
|
||
describe "REST::Error" do | ||
it "extends any Timeout related exception" do | ||
classes = REST::Error::Timeout.classes | ||
classes.should.not.be.empty | ||
classes.each do |error_class| | ||
lambda { raise error_class }.should.raise REST::Error::Timeout | ||
lambda { raise error_class }.should.raise REST::Error | ||
end | ||
end | ||
|
||
it "extends any Connection related exception" do | ||
classes = REST::Error::Connection.classes | ||
classes.should.not.be.empty | ||
classes.each do |error_class| | ||
lambda { raise error_class }.should.raise REST::Error::Connection | ||
lambda { raise error_class }.should.raise REST::Error | ||
end | ||
end | ||
|
||
it "extends any Protocol related exception" do | ||
classes = REST::Error::Protocol.classes | ||
classes.should.not.be.empty | ||
classes.each do |error_class| | ||
lambda { raise error_class }.should.raise REST::Error::Protocol | ||
lambda { raise error_class }.should.raise REST::Error | ||
end | ||
end | ||
end |