Skip to content

Commit

Permalink
#2070 Retrying Twilio 400 Errors (#2152)
Browse files Browse the repository at this point in the history
  • Loading branch information
mchlwellman authored Dec 4, 2024
1 parent 3613186 commit d2d9cb3
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 7 deletions.
8 changes: 7 additions & 1 deletion app/clients/sms/twilio.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ class TwilioSMSClient(SmsClient):
'21610': TwilioStatus(21610, NOTIFICATION_PERMANENT_FAILURE, OPT_OUT_MESSAGE),
'21612': TwilioStatus(21612, NOTIFICATION_PERMANENT_FAILURE, 'Invalid to/from combo'),
'21614': TwilioStatus(21614, NOTIFICATION_PERMANENT_FAILURE, 'Non-mobile number'),
'21617': TwilioStatus(21617, NOTIFICATION_PERMANENT_FAILURE, 'Message too long'),
'21635': TwilioStatus(21635, NOTIFICATION_PERMANENT_FAILURE, 'Non-mobile number'),
'30001': TwilioStatus(30001, NOTIFICATION_TEMPORARY_FAILURE, 'Queue overflow'),
'30002': TwilioStatus(30002, NOTIFICATION_PERMANENT_FAILURE, 'Account suspended'),
Expand Down Expand Up @@ -175,7 +176,6 @@ def send_sms(
Return: a string containing the Twilio message.sid
"""

start_time = monotonic()
from app.dao.service_sms_sender_dao import (
dao_get_service_sms_sender_by_service_id_and_number,
Expand Down Expand Up @@ -238,6 +238,12 @@ def send_sms(
if e.status == 400 and 'phone number' in e.msg:
self.logger.exception('Twilio send SMS request for %s failed', reference)
raise InvalidProviderException from e
elif e.status == 400 and e.code == 21617: # Twilio error code for max length exceeded
self.logger.exception(
'Twilio send SMS request for %s failed, message content max length exceeded.', reference
)
self.logger.debug('Twilio error details for %s - %s: %s', reference, e.code, e.msg)
raise NonRetryableException('Twilio request failed') from e
else:
raise
except:
Expand Down
36 changes: 30 additions & 6 deletions tests/app/clients/test_twilio.py
Original file line number Diff line number Diff line change
Expand Up @@ -599,19 +599,43 @@ def test_send_sms_twilio_callback(
assert response_dict['sid'] == twilio_sid


def test_send_sms_raises_invalid_provider_error_with_invalid_twilio_number(
@pytest.mark.parametrize(
(
'response_dict',
'exception',
),
(
(
{
'code': 21606,
'message': "The 'From' phone number provided (+61412345678) is not a valid message-capable Twilio phone number for this destination",
},
InvalidProviderException,
),
(
{
'code': 21617,
'message': 'Unable to create record: The concatenated message body exceeds the 1600 character limit',
},
NonRetryableException,
),
),
ids=(
'invalid-from-number',
'message-too-long',
),
)
def test_send_sms_raises_non_retryable_exception_with_invalid_request(
notify_api,
mocker,
response_dict,
exception,
):
to = '+61412345678'
content = 'my message'
reference = 'my reference'
response_dict = {
'code': 21606,
'message': "The 'From' phone number provided (+61412345678) is not a valid message-capable Twilio phone number for this destination",
}

with pytest.raises(InvalidProviderException):
with pytest.raises(exception):
with requests_mock.Mocker() as r_mock:
r_mock.post(
f'https://api.twilio.com/2010-04-01/Accounts/{twilio_sms_client._account_sid}/Messages.json',
Expand Down

0 comments on commit d2d9cb3

Please sign in to comment.