mirror of
https://github.com/pacnpal/django-anymail.git
synced 2025-12-20 03:41:05 -05:00
Improve MandrillAPIError.__str__
* Include formatted response from Mandrill API (if any) * Clean up recipient address(es)
This commit is contained in:
@@ -1,3 +1,4 @@
|
|||||||
|
import json
|
||||||
from requests import HTTPError
|
from requests import HTTPError
|
||||||
import warnings
|
import warnings
|
||||||
|
|
||||||
@@ -14,8 +15,15 @@ class MandrillAPIError(HTTPError):
|
|||||||
message = "Mandrill API response %d" % self.status_code
|
message = "Mandrill API response %d" % self.status_code
|
||||||
if self.log_message:
|
if self.log_message:
|
||||||
message += "\n" + self.log_message
|
message += "\n" + self.log_message
|
||||||
if self.response:
|
# Include the Mandrill response, nicely formatted, if possible
|
||||||
message += "\nResponse: " + getattr(self.response, 'content', "")
|
try:
|
||||||
|
json_response = self.response.json()
|
||||||
|
message += "\nMandrill response:\n" + json.dumps(json_response, indent=2)
|
||||||
|
except (AttributeError, KeyError, ValueError): # not JSON = ValueError
|
||||||
|
try:
|
||||||
|
message += "\nMandrill response: " + self.response.text
|
||||||
|
except AttributeError:
|
||||||
|
pass
|
||||||
return message
|
return message
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -137,15 +137,16 @@ class DjrillBackend(BaseEmailBackend):
|
|||||||
message.mandrill_response = None
|
message.mandrill_response = None
|
||||||
|
|
||||||
if not self.fail_silently:
|
if not self.fail_silently:
|
||||||
from_email = msg_dict.get('from_email', None)
|
log_message = "Failed to send a message"
|
||||||
from_message = ""
|
if 'to' in msg_dict:
|
||||||
if from_email:
|
log_message += " to " + ','.join(
|
||||||
from_message = ", from %s" % from_email
|
to['email'] for to in msg_dict.get('to', []) if 'email' in to)
|
||||||
|
if 'from_email' in msg_dict:
|
||||||
|
log_message += " from %s" % msg_dict['from_email']
|
||||||
raise MandrillAPIError(
|
raise MandrillAPIError(
|
||||||
status_code=response.status_code,
|
status_code=response.status_code,
|
||||||
response=response,
|
response=response,
|
||||||
log_message="Failed to send a message to %s%s" %
|
log_message=log_message)
|
||||||
(msg_dict['to'], from_message))
|
|
||||||
return False
|
return False
|
||||||
|
|
||||||
# add the response from mandrill to the EmailMessage so callers can inspect it
|
# add the response from mandrill to the EmailMessage so callers can inspect it
|
||||||
|
|||||||
@@ -308,6 +308,31 @@ class DjrillBackendTests(DjrillBackendMockAPITestCase):
|
|||||||
['to@example.com'], fail_silently=True)
|
['to@example.com'], fail_silently=True)
|
||||||
self.assertEqual(sent, 0)
|
self.assertEqual(sent, 0)
|
||||||
|
|
||||||
|
def test_api_error_includes_details(self):
|
||||||
|
"""MandrillAPIError should include Mandrill's error message"""
|
||||||
|
msg = mail.EmailMessage('Subject', 'Body', 'from@example.com', ['to@example.com'])
|
||||||
|
|
||||||
|
# JSON error response:
|
||||||
|
error_response = b"""{
|
||||||
|
"status": "error",
|
||||||
|
"code": 12,
|
||||||
|
"name": "Error_Name",
|
||||||
|
"message": "Helpful explanation from Mandrill"
|
||||||
|
}"""
|
||||||
|
self.mock_post.return_value = self.MockResponse(status_code=400, raw=error_response)
|
||||||
|
with self.assertRaisesMessage(MandrillAPIError, "Helpful explanation from Mandrill"):
|
||||||
|
msg.send()
|
||||||
|
|
||||||
|
# Non-JSON error response:
|
||||||
|
self.mock_post.return_value = self.MockResponse(status_code=500, raw=b"Invalid API key")
|
||||||
|
with self.assertRaisesMessage(MandrillAPIError, "Invalid API key"):
|
||||||
|
msg.send()
|
||||||
|
|
||||||
|
# No content in the error response:
|
||||||
|
self.mock_post.return_value = self.MockResponse(status_code=502, raw=None)
|
||||||
|
with self.assertRaises(MandrillAPIError):
|
||||||
|
msg.send()
|
||||||
|
|
||||||
|
|
||||||
class DjrillMandrillFeatureTests(DjrillBackendMockAPITestCase):
|
class DjrillMandrillFeatureTests(DjrillBackendMockAPITestCase):
|
||||||
"""Test Djrill backend support for Mandrill-specific features"""
|
"""Test Djrill backend support for Mandrill-specific features"""
|
||||||
|
|||||||
@@ -76,6 +76,8 @@ Version 1.4 (development):
|
|||||||
(Specifying a :ref:`Reply-To header <message-headers>`
|
(Specifying a :ref:`Reply-To header <message-headers>`
|
||||||
still works, with any version of Django,
|
still works, with any version of Django,
|
||||||
and will override the reply_to param if you use both.)
|
and will override the reply_to param if you use both.)
|
||||||
|
* Include Mandrill error response in str(MandrillAPIError),
|
||||||
|
to make errors easier to understand.
|
||||||
* More-helpful exception when using a non-JSON-serializable
|
* More-helpful exception when using a non-JSON-serializable
|
||||||
type in merge_vars and other Djrill message attributes
|
type in merge_vars and other Djrill message attributes
|
||||||
* Deprecation warnings for upcoming 2.0 changes (see above)
|
* Deprecation warnings for upcoming 2.0 changes (see above)
|
||||||
|
|||||||
Reference in New Issue
Block a user