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
|
Struct::AppLink::Native::Android
|
||||||
when :windows_phone
|
when :windows_phone
|
||||||
Struct::AppLink::Native::WindowsPhone
|
Struct::AppLink::Native::WindowsPhone
|
||||||
else
|
|
||||||
raise 'Unknown AppLink Type'
|
|
||||||
end
|
end
|
||||||
klass.new link
|
klass.new link
|
||||||
end
|
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
|
when 200...300
|
||||||
_response_
|
_response_
|
||||||
else
|
else
|
||||||
# TODO: better exception structure
|
raise Exception.detect(response.status, _response_, response.headers)
|
||||||
raise response.body
|
|
||||||
end
|
end
|
||||||
rescue MultiJson::DecodeError
|
rescue MultiJson::DecodeError
|
||||||
# TODO: better exception structure
|
raise Exception.new(response.status, "Unparsable Response: #{response.body}")
|
||||||
raise response.body
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
|
@ -103,8 +103,8 @@ describe FbGraph2::Node do
|
||||||
instance.fetch
|
instance.fetch
|
||||||
end
|
end
|
||||||
end.to raise_error { |e|
|
end.to raise_error { |e|
|
||||||
e.should be_instance_of RuntimeError
|
e.should be_instance_of FbGraph2::Exception::BadRequest
|
||||||
e.message.should == mock_json('error/400/2500')
|
e.message.should == mock_json('error/400/2500')[:error][:message]
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -116,8 +116,8 @@ describe FbGraph2::Node do
|
||||||
instance.fetch
|
instance.fetch
|
||||||
end
|
end
|
||||||
end.to raise_error { |e|
|
end.to raise_error { |e|
|
||||||
e.should be_instance_of RuntimeError
|
e.should be_instance_of FbGraph2::Exception
|
||||||
e.message.should == mock_json('error/invalid_format')
|
e.message.should == "Unparsable Response: #{mock_json('error/invalid_format')}"
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -23,7 +23,10 @@ module MockGraph
|
||||||
end
|
end
|
||||||
|
|
||||||
def mock_json(response_path)
|
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
|
end
|
||||||
|
|
||||||
def request_to(path, method = :get, options = {})
|
def request_to(path, method = :get, options = {})
|
||||||
|
|
Loading…
Reference in a new issue