1

Currently have this snippet set up in my tasks.py so that an email is sent to the Django project's admins by huey whenever a task fails:

from django.core.mail import mail_admins

from huey import signals
from huey.contrib import djhuey as huey


@huey.signal(signals.SIGNAL_ERROR)
def task_error(signal, task, exc):
    subject = f'Task [{task.name}] failed
    message = f"""Task ID: {task.id}'
Args: {task.args}
Kwargs: {task.kwargs}
Exception: {exc}"""
    mail_admins(subject, message)

This results in the following (example) email subject

[Django] Task [test_task] failed

and body:

Task ID: 89e4bfb3-3cd3-4d6f-8693-68874caf21ec
Args: (123,)
Kwargs: {}
Exception: division by zero

which is pretty slick but... questions:

  1. Right now, this is triggered whenever a task fails, including retries. I would like it to be sent only in the case all retries failed. So if a task has retries=2, right now I receive 3 emails (original error + 2 retries). How to have it send the email only on the last retry?
  2. Is there a way to print the exception's exc traceback?

P.S. I tried setting it up via Django project logging, but this approach offers finer-grained control, so I'm satisfied with it.

Update

The module with updates based on @Adam Chainz & @coleifer's answers (both correct), now looks like:

import traceback

from django.core.mail import mail_admins

from huey import signals
from huey.contrib import djhuey as huey


@huey.signal(signals.SIGNAL_ERROR)
def task_error(signal, task, exc):
    if task.retries > 0:
        return
    subject = f'Task [{task.name}] failed'
    message = f"""Task ID: {task.id}
Args: {task.args}
Kwargs: {task.kwargs}
Exception: {exc}
{traceback.format_exc()}"""
    mail_admins(subject, message)
Joseph Victor Zammit
  • 14,760
  • 10
  • 76
  • 102

2 Answers2

1

See: https://docs.python.org/3.6/library/traceback.html

Since you have the task instance you should be able to check if retries==0.

A more standard way to do this is to attach an email handler at loglevel ERROR to the huey consumer logger. That's the way I would handle it.

coleifer
  • 24,887
  • 6
  • 60
  • 75
  • Thanks @coleifer. I did attach the `mail_admins` to the "huey consumer logger" `huey.consumer`. However that basically "swallows" all other types of log levels; for example, no output is shown when running `manage.py run_huey` locally. – Joseph Victor Zammit Feb 21 '20 at 16:44
1

On 1. I think you can check task.retries?

On 2. use traceback.format_exception ?

Adam Johnson
  • 471
  • 1
  • 5
  • 11