1
0
Fork 0
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:
nov 2014-06-11 17:45:05 +09:00
parent 968cab225d
commit 8ab35f58ea
5 changed files with 91 additions and 11 deletions

View file

@ -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

View 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

View file

@ -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

View file

@ -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

View file

@ -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 = {})