Skip to content

Commit

Permalink
Add error handling for different responses
Browse files Browse the repository at this point in the history
Considering more responses structures while parsing errors and adding tests.
  • Loading branch information
pablonahuelgomez committed Feb 12, 2018
1 parent 1de36fd commit 05b4f37
Show file tree
Hide file tree
Showing 2 changed files with 81 additions and 19 deletions.
64 changes: 47 additions & 17 deletions lib/exponent-server-sdk.rb
Original file line number Diff line number Diff line change
Expand Up @@ -22,29 +22,37 @@ def publish(messages)

private

attr_reader :http_client

def handle_response(response)
case response.code.to_s
when /(^4|^5)/
error = extract_error(parse_json(response))
raise Error, "#{error.fetch('code')} -> #{error.fetch('message')}"
raise Error, build_error_from_failure(parse_json(response))
else
handle_success(parse_json(response).fetch('data').first)
handle_success(parse_json(response))
end
end

def parse_json(response)
JSON.parse(response.body)
end

def extract_error(body)
if body.respond_to?(:fetch)
body.fetch('errors').first { unknown_error }
else
unknown_error
def build_error_from_failure(response)
build_error_with_handling(response) do
extract_error_from_response(response)
end
end

attr_reader :http_client
def extract_error_from_response(response)
error = response.fetch('errors').first { unknown_error_format(response) }
"#{error.fetch('code')} -> #{error.fetch('message')}"
end

def build_error_with_handling(response)
yield(response)
rescue KeyError
unknown_error_format(response)
end

def push_notifications(messages)
http_client.post(
Expand All @@ -66,16 +74,38 @@ def headers
}
end

def handle_success(data)
return data if data.fetch('status') == 'ok'
raise Exponent::Push::Error, "#{data['details']['error']} -> #{data['message']}"
def handle_success(response)
data = extract_data(response)
if data.fetch('status') == 'ok'
data
else
raise Error, build_error_from_success(response)
end
end

def unknown_error
{
'code' => 'Unknown code',
'message' => 'Unknown message'
}
def build_error_from_success(response)
build_error_with_handling(response) do
extract_error_from_success(response)
end
end

def extract_error_from_success(response)
data = extract_data(response)
message = data.fetch('message')

if data['details']
"#{data.fetch('details').fetch('error')} -> #{message}"
else
"#{data.fetch('status')} -> #{message}"
end
end

def extract_data(response)
response.fetch('data').first
end

def unknown_error_format(response)
"Unknown error format: #{response}"
end
end
end
Expand Down
36 changes: 34 additions & 2 deletions test/exponent-server-sdk-test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -22,26 +22,48 @@ def test_publish_with_success
def test_publish_with_error
@response_mock.expect(:code, 400)
@response_mock.expect(:body, error_body.to_json)
message = 'INTERNAL_SERVER_ERROR -> An unknown error occurred.'

@mock.expect(:post, @response_mock, client_args)

assert_raises Exponent::Push::Error do
exception = assert_raises Exponent::Push::Error do
@exponent.publish(messages)
end

assert_equal(message, exception.message)

@mock.verify
end

def test_publish_with_success_and_errors
@response_mock.expect(:code, 200)
@response_mock.expect(:body, success_with_error_body.to_json)
message = 'DeviceNotRegistered -> "ExponentPushToken[42]" is not a registered push notification recipient'

@mock.expect(:post, @response_mock, client_args)

assert_raises Exponent::Push::Error do
exception = assert_raises Exponent::Push::Error do
@exponent.publish(messages)
end

assert_equal(message, exception.message)

@mock.verify
end

def test_publish_with_success_and_apn_error
@response_mock.expect(:code, 200)
@response_mock.expect(:body, success_with_apn_error_body.to_json)
message = 'error -> Could not find APNs credentials for you (your_app). Check whether you are trying to send a notification to a detached app.'

@mock.expect(:post, @response_mock, client_args)

exception = assert_raises Exponent::Push::Error do
@exponent.publish(messages)
end

assert_equal(message, exception.message)

@mock.verify
end

Expand Down Expand Up @@ -70,6 +92,16 @@ def success_with_error_body
}
end

def success_with_apn_error_body
{
'data' => [{
'status' => 'error',
'message' =>
'Could not find APNs credentials for you (your_app). Check whether you are trying to send a notification to a detached app.'
}]
}
end

def client_args
[
'https://exp.host/--/api/v2/push/send',
Expand Down

0 comments on commit 05b4f37

Please sign in to comment.