Skip to content

Commit 5db0ca9

Browse files
Merge pull request #194 from afonso-aguas/fix/parse-body-before-error-check
Fix false-positive HttpResponseError on bodies containing "error" substring
2 parents 858b024 + 616dff6 commit 5db0ca9

4 files changed

Lines changed: 83 additions & 5 deletions

File tree

lib/whatsapp_sdk/api/client.rb

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -58,13 +58,13 @@ def send_request(endpoint: "", full_url: nil, http_method: "post", params: {}, h
5858

5959
response = faraday_request.public_send(http_method, endpoint, request_params(params, headers), headers)
6060

61-
if response.status > 499 || Api::Responses::GenericErrorResponse.response_error?(response: response.body)
62-
raise Api::Responses::HttpResponseError.new(http_status: response.status, body: JSON.parse(response.body))
63-
end
61+
parsed_body = parse_response_body(response.body)
6462

65-
return nil if response.body == ""
63+
if response.status > 499 || Api::Responses::GenericErrorResponse.response_error?(response: parsed_body)
64+
raise Api::Responses::HttpResponseError.new(http_status: response.status, body: parsed_body)
65+
end
6666

67-
JSON.parse(response.body)
67+
parsed_body
6868
end
6969

7070
def download_file(url:, content_type_header:, file_path: nil)
@@ -85,6 +85,12 @@ def download_file(url:, content_type_header:, file_path: nil)
8585

8686
private
8787

88+
def parse_response_body(body)
89+
return nil if body.nil? || body.empty?
90+
91+
JSON.parse(body)
92+
end
93+
8894
def request_params(params, headers)
8995
return params.to_json if params.is_a?(Hash) && headers['Content-Type'] == 'application/json'
9096

lib/whatsapp_sdk/api/responses/generic_error_response.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ def initialize(response:)
1616
end
1717

1818
def self.response_error?(response:)
19+
return false unless response.is_a?(Hash)
20+
1921
response["error"]
2022
end
2123

test/whatsapp/api/client_test.rb

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,43 @@ def test_send_request_delete_with_success_response
5151
assert_nil(response_body)
5252
end
5353

54+
def test_send_request_does_not_raise_when_body_text_contains_error_substring
55+
payload = {
56+
'data' => [{
57+
'name' => 'dia_push',
58+
'components' => [{ 'type' => 'BODY', 'text' => 'si tu cupón te da algún error, avísanos' }]
59+
}]
60+
}
61+
stub_test_request(:get, response_body: payload)
62+
63+
response_body = @client.send_request(endpoint: 'test', http_method: 'get')
64+
65+
assert_equal(payload, response_body)
66+
end
67+
68+
def test_send_request_raises_when_response_has_error_key
69+
error_body = { 'error' => { 'message' => 'Invalid OAuth token', 'code' => 190 } }
70+
stub_test_request(:get, response_status: 400, response_body: error_body)
71+
72+
error = assert_raises(Api::Responses::HttpResponseError) do
73+
@client.send_request(endpoint: 'test', http_method: 'get')
74+
end
75+
76+
assert_equal(400, error.http_status)
77+
assert_equal(error_body, error.body)
78+
end
79+
80+
def test_send_request_raises_for_5xx_responses
81+
error_body = { 'error' => { 'message' => 'Internal server error' } }
82+
stub_test_request(:get, response_status: 502, response_body: error_body)
83+
84+
error = assert_raises(Api::Responses::HttpResponseError) do
85+
@client.send_request(endpoint: 'test', http_method: 'get')
86+
end
87+
88+
assert_equal(502, error.http_status)
89+
end
90+
5491
def test_set_api_version_in_config
5592
WhatsappSdk.configure do |config|
5693
config.api_version = 'v16.0'
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# typed: true
2+
# frozen_string_literal: true
3+
4+
require 'test_helper'
5+
require 'api/responses/generic_error_response'
6+
7+
module WhatsappSdk
8+
module Api
9+
module Responses
10+
class GenericErrorResponseTest < Minitest::Test
11+
def test_response_error_returns_truthy_for_hash_with_error_key
12+
response = { "error" => { "message" => "Invalid OAuth token", "code" => 190 } }
13+
assert_equal({ "message" => "Invalid OAuth token", "code" => 190 },
14+
GenericErrorResponse.response_error?(response: response))
15+
end
16+
17+
def test_response_error_returns_nil_for_hash_without_error_key
18+
response = { "data" => [{ "id" => "1" }] }
19+
assert_nil(GenericErrorResponse.response_error?(response: response))
20+
end
21+
22+
def test_response_error_returns_false_for_string_input
23+
body = '{"data":[{"text":"si tu cupón te da algún error, avísanos"}]}'
24+
assert_equal(false, GenericErrorResponse.response_error?(response: body))
25+
end
26+
27+
def test_response_error_returns_false_for_nil_input
28+
assert_equal(false, GenericErrorResponse.response_error?(response: nil))
29+
end
30+
end
31+
end
32+
end
33+
end

0 commit comments

Comments
 (0)