I’d like to move this forward to make room for EMAIL_PROVIDERS. From that lack of responses, I gather nobody has strong opinions one way or the other. Which isn’t surprising: I’m pretty sure fail_silently doesn’t show up much in production Django code.
Unless there’s further (human) input, I’ll open a ticket to deprecate fail_silently for everything except mail_admins() and mail_managers()—option 3 below.
I poked into fail_silently usage through GitHub code search, then asked three AIs for a broader perspective on how it’s used in projects they’ve seen. (I hoped their training data might supply the answer to my earlier question, “Is there some use case I’m missing?” The AI analyses seemed to align with patterns I had spotted in my GitHub search.)
My takeaways:
- The overwhelming majority of django.core.mail calls use the default
fail_silently=False. (It’s unusual to ignore email errors in production. This decision just doesn’t impact that much code.) - Many uses of
fail_silently=Truewere likely copied from older tutorials or references, for no good reason. (Two AI’s referred to “cargo culting.”) - Where
fail_silently=Trueis intentional, callers seem to have different expectations for which errors would be silenced. Many want “don’t crash this path” (ignore all errors), but others seem to be saying “don’t bother me with network glitches” and would want other errors to be loud. - The exception is mail_admins(): when it’s called with
fail_silently=True(which is also rare), it’s in error handling paths that want to avoid cascading errors. Callers expect it to suppress all exceptions. (The same argument probably applies to mail_managers(), but that function isn’t widely used.) - All uses of
fail_silentlyexpect it to apply to that one send—nobody thinks of it as EmailBackend configuration.
I see three options:
-
Make
fail_silentlyignore allExceptions (broad try/catch in EmailMessage.send() as described in the first post in this thread; GPT and Claude both wanted to refine this to not ignoreMemoryErrororRecursionError) -
Deprecate
fail_silentlyand remove it in Django 7.0. Callers would need to replacefail_silently=Truewith their own exception handling, forcing them to be explicit about which (if any) exceptions they want to ignore (second post in this thread) -
Hybrid approach: Keep
fail_silentlyfor mail_admins() and mail_managers() (ignoring allExceptions), but deprecate and remove it for send_mail(), send_mass_mail() and EmailMessage.send().
I’ve tried to map the AIs’ opinions to our usual voting scale:
| Mike (human) | Claude 4.6 Opus | Gemini 3.1 Pro | GPT 5.3 Codex | |
|---|---|---|---|---|
| Option 1 | +0 | +1 | +0 | +1 |
| Option 2 | -1 | -1 | -1 | -1 |
| Option 3 | +1 | -0 | +1 | -1 |
Gemini and I both feel option 3 is pragmatic for real-world use, and easy to explain and document. (I think GPT’s a little alarmist about the impact of removing it, so I’m discounting its -1 on option 3.)
Full chat transcripts: * django.core.mail fail_silently usage.md · GitHub. (The options were discussed in a different order from above: 1=A, 2=C, 3=B.)