mirror of
https://github.com/nov/fb_graph2
synced 2023-03-27 23:22:15 -04:00
better exception handling
This commit is contained in:
parent
968cab225d
commit
8ab35f58ea
5 changed files with 91 additions and 11 deletions
|
@ -25,8 +25,6 @@ module FbGraph2
|
|||
Struct::AppLink::Native::Android
|
||||
when :windows_phone
|
||||
Struct::AppLink::Native::WindowsPhone
|
||||
else
|
||||
raise 'Unknown AppLink Type'
|
||||
end
|
||||
klass.new link
|
||||
end
|
||||
|
|
81
lib/fb_graph2/exception.rb
Normal file
81
lib/fb_graph2/exception.rb
Normal file
|
@ -0,0 +1,81 @@
|
|||
module FbGraph2
|
||||
class Exception < StandardError
|
||||
attr_accessor :status, :type, :code
|
||||
|
||||
class << self
|
||||
def detect(status, body = {}, headers = {})
|
||||
error = body[:error]
|
||||
message = error.try(:[], :message)
|
||||
klass = detect_from_header(headers, error) || detect_from_status(status)
|
||||
if klass
|
||||
klass.new message, error
|
||||
else
|
||||
new status, message, error
|
||||
end
|
||||
end
|
||||
|
||||
def detect_from_status(status)
|
||||
case status
|
||||
when 400
|
||||
BadRequest
|
||||
when 401
|
||||
Unauthorized
|
||||
when 404
|
||||
NotFound
|
||||
when 500
|
||||
InternalServerError
|
||||
end
|
||||
end
|
||||
|
||||
def detect_from_header(headers, error)
|
||||
key, value = headers.detect do |name, value|
|
||||
name.upcase == "WWW-Authenticate".upcase
|
||||
end || return
|
||||
matched, klass = ERROR_HEADER_MATCHERS.detect do |matcher, klass_name|
|
||||
matcher =~ value
|
||||
end || return
|
||||
klass
|
||||
end
|
||||
end
|
||||
|
||||
def initialize(status, message, error = {})
|
||||
super message
|
||||
self.status = status
|
||||
self.type = error[:type]
|
||||
self.code = error[:code]
|
||||
end
|
||||
|
||||
class BadRequest < Exception
|
||||
def initialize(message, details = {})
|
||||
super 400, message, details
|
||||
end
|
||||
end
|
||||
|
||||
class Unauthorized < Exception
|
||||
def initialize(message, details = {})
|
||||
super 401, message, details
|
||||
end
|
||||
end
|
||||
|
||||
class NotFound < Exception
|
||||
def initialize(message, details = {})
|
||||
super 404, message, details
|
||||
end
|
||||
end
|
||||
|
||||
class InternalServerError < Exception
|
||||
def initialize(message, details = {})
|
||||
super 500, message, details
|
||||
end
|
||||
end
|
||||
|
||||
class InvalidToken < Unauthorized; end
|
||||
class InvalidRequest < BadRequest; end
|
||||
|
||||
ERROR_HEADER_MATCHERS = {
|
||||
/not_found/ => NotFound,
|
||||
/invalid_token/ => InvalidToken,
|
||||
/invalid_request/ => InvalidRequest
|
||||
}
|
||||
end
|
||||
end
|
|
@ -107,12 +107,10 @@ module FbGraph2
|
|||
when 200...300
|
||||
_response_
|
||||
else
|
||||
# TODO: better exception structure
|
||||
raise response.body
|
||||
raise Exception.detect(response.status, _response_, response.headers)
|
||||
end
|
||||
rescue MultiJson::DecodeError
|
||||
# TODO: better exception structure
|
||||
raise response.body
|
||||
raise Exception.new(response.status, "Unparsable Response: #{response.body}")
|
||||
end
|
||||
end
|
||||
end
|
|
@ -103,8 +103,8 @@ describe FbGraph2::Node do
|
|||
instance.fetch
|
||||
end
|
||||
end.to raise_error { |e|
|
||||
e.should be_instance_of RuntimeError
|
||||
e.message.should == mock_json('error/400/2500')
|
||||
e.should be_instance_of FbGraph2::Exception::BadRequest
|
||||
e.message.should == mock_json('error/400/2500')[:error][:message]
|
||||
}
|
||||
end
|
||||
end
|
||||
|
@ -116,8 +116,8 @@ describe FbGraph2::Node do
|
|||
instance.fetch
|
||||
end
|
||||
end.to raise_error { |e|
|
||||
e.should be_instance_of RuntimeError
|
||||
e.message.should == mock_json('error/invalid_format')
|
||||
e.should be_instance_of FbGraph2::Exception
|
||||
e.message.should == "Unparsable Response: #{mock_json('error/invalid_format')}"
|
||||
}
|
||||
end
|
||||
end
|
||||
|
|
|
@ -23,7 +23,10 @@ module MockGraph
|
|||
end
|
||||
|
||||
def mock_json(response_path)
|
||||
response_for(response_path)[:body].read
|
||||
content = response_for(response_path)[:body].read
|
||||
MultiJson.load(content).with_indifferent_access
|
||||
rescue MultiJson::DecodeError
|
||||
content
|
||||
end
|
||||
|
||||
def request_to(path, method = :get, options = {})
|
||||
|
|
Loading…
Reference in a new issue