brack3t / Djrill

[INACTIVE/UNMAINTAINED] Djrill is an email backend and new message class for Django users that want to take advantage of the Mandrill transactional email service from MailChimp.
BSD 3-Clause "New" or "Revised" License
319 stars 64 forks source link

Suggestion: return Mandrill response from the _send method #34

Closed guillaumepiot closed 11 years ago

guillaumepiot commented 11 years ago

Hi there,

I would like to know if it was possible to return the Mandrill API response rather than just a boolean from the _send method in the backend.

I'm building an email log on top of Djrill so it will be useful to log the status to be able to troubleshoot any possible error.

Please let me know if you think it could work.

Guillaume

medmunds commented 11 years ago

Guillaume, I'm a little confused about how you're calling _send directly. Are you constructing a DjrillBackend and feeding messages to its _send method? (Rather than calling an EmailMessage object's send?) If so... I'm not sure you really want to do that.

In theory, we can change anything we want about the _send method. It's an internal function (signified by the leading underscore), so its behavior is subject to change without notice. But that's precisely why you wouldn't want to write code that depends on calling it directly -- it might just change out from under you again in some future release.

I can imagine a lot of different things you might mean by "email log". Here are some options that might be helpful:

Mandrill also has some logging facilities of its own, independent of Djrill. Their control panel logs the last 100 failed API calls, which is really helpful for troubleshooting. And if you want to keep a record of all outgoing messages, they have a bcc setting that can be useful.

If none of this covers your use case, maybe you could provide some more detail about what you're trying to accomplish, and we might have some other ideas.

guillaumepiot commented 11 years ago

Hi there,

And thank you for the informative reply, you've just taught me a few more things about Mandrill!

What I'm trying to do is too grab the Mandrill API response back from the msg.send() method and save it against a mail log in the database.

I can see that the error response is being raised as an exception, which is fine, but I'm not sure if I can grab that exception message and save in the email log.

That way, I could review the logs in the db, and try to identify the reason why it didn't get processed by Mandrill.

Here's an example scenario I would like to implement:

response = msg.send()

if response['status'] == 'error':
    save_log(status=response['status'] response=response['message'])
else:
    save_log(status=response['status'])

So I imagined if the _send() method returned the response in non-debug mode rather than raise an error then I would be able to log the error or success in accordingly.

Thanks

Guillaume

medmunds commented 11 years ago

Ah, OK. msg.send() is actually Django's EmailMessage.send(). It's defined by Django to return the number of emails that were sent (zero or one), and there's nothing we could do to change that.

You can catch the errors raised by msg.send in order to log them. Perhaps something like this (untested code):

try:
    num_sent = msg.send()
    if num_sent > 0:
        save_log("success")
    else:
        save_log("nothing to send")
except MandrillAPIError as error:
    save_log("error from Mandrill API", error.response.content)
except requests.RequestException as error:
    save_log("error connecting to Mandrill", str(error))

That said, you're probably not going to catch very many real-world errors this way. The only MandrillAPIErrors I've ever seen are configuration issues: you've got the wrong API key, you're trying to use a Mandrill template that doesn't exist, etc. We do occasionally see transient connection errors in our production site. (We use the django-mailer app, which automatically retries the send later once connectivity to Mandrill is restored.)

Also, errors in delivering the email won't show up here at all. Mandrill only queues a message when we call its send API, so a success response only means it's been accepted into the queue. There's no way to determine whether a particular email can actually be sent until Mandrill gets around to delivering it out of the queue, which is some time later. (And no way to determine whether that email will reach its destination until sometimes much later.)