From 211d844befcec90fb6e55e1b88c74b802e7cbb7d Mon Sep 17 00:00:00 2001 From: Leandro de Souza <85115541+leandrodesouzadev@users.noreply.github.com> Date: Wed, 27 Sep 2023 17:41:18 -0300 Subject: [PATCH] Integrar discord para report de erros (#15) * Feat (error reporting): Adds error reporting functionality to the core app * Feat (push_notifications): Adds some logging to the services * Fix (users): Verbose name * I18n: Adds more translations * Fix (tests): Adds new argument, and fixture for logging --- README.md | 69 +++++ docs/request_failed_error_report.png | Bin 0 -> 63458 bytes docs/task_failed_error_report.png | Bin 0 -> 72161 bytes local.yml | 2 +- locale/pt_BR/LC_MESSAGES/django.po | 269 +++++++++++------- pdm.lock | 12 +- pyproject.toml | 1 + src/app/celery/app.py | 22 +- src/app/ext/messaging/__init__.py | 0 src/app/ext/messaging/abc.py | 98 +++++++ src/app/ext/messaging/backends/__init__.py | 0 src/app/ext/messaging/backends/discord.py | 71 +++++ src/app/ext/messaging/backends/stdout.py | 41 +++ src/app/logging/__init__.py | 0 src/app/logging/types.py | 79 +++++ src/app/logging/utils.py | 28 ++ src/app/middlewares/log.py | 21 ++ src/app/services.py | 97 +++++++ src/app/settings/conf.py | 3 + .../settings/external_services/messaging.py | 8 + src/app/settings/infra/reporting.py | 13 + src/push_notifications/services.py | 28 +- src/push_notifications/tasks.py | 2 - src/users/migrations/0001_initial.py | 2 +- src/users/models.py | 2 +- tests/conftest.py | 7 + .../test_push_notification_delivery_failed.py | 4 +- 27 files changed, 764 insertions(+), 115 deletions(-) create mode 100644 docs/request_failed_error_report.png create mode 100644 docs/task_failed_error_report.png create mode 100644 src/app/ext/messaging/__init__.py create mode 100644 src/app/ext/messaging/abc.py create mode 100644 src/app/ext/messaging/backends/__init__.py create mode 100644 src/app/ext/messaging/backends/discord.py create mode 100644 src/app/ext/messaging/backends/stdout.py create mode 100644 src/app/logging/__init__.py create mode 100644 src/app/logging/types.py create mode 100644 src/app/logging/utils.py create mode 100644 src/app/middlewares/log.py create mode 100644 src/app/services.py create mode 100644 src/app/settings/external_services/messaging.py create mode 100644 src/app/settings/infra/reporting.py diff --git a/README.md b/README.md index 9c0a6a5..1a3ef0c 100644 --- a/README.md +++ b/README.md @@ -416,6 +416,14 @@ def person_spam(*, person, sms_service: SMSExternalService): ``` Este decorator irá encontrar o parâmetro que tem a mesma tipagem que o serviço que deve ser injetado e quando a função for chamada, injetará uma instância do objeto daquela classe na função, se a função foi chamada sem o argumento que deve ser injetado. + +### Logs + +Nesta camada da aplicação é importante ter logs "razoáveis", por isso aproveite ao máximo as funcionalidades builtin do python, como os níveis de log, que são facilmente configurados via variáveis de ambiente. + +> Caso algum erro aconteça em seu serviço, o melhor a fazer é reportar este erro. Veja a seção [Report de erros](#loggingreport-de-erros) + + ### Testes Como aqui será a parte mais importante da sua aplicação, onde todas as regras de negócio estarão, escreva testes extensivos para esta camada. Cada exceção que for levantada, deve ter um teste correspondente. Cada ramificação `if`, e assim por diante. Se você seguir as diretrizes deste style guide, testar esta camada será simples! @@ -494,6 +502,67 @@ Algumas considerações: As configurações dos serviços externos estão definidas na seção [Configurações](#configurações) + +## Logging/Report de erros + +Este boilerplate já vem integrado com um report de erro, que envia uma mensagem com alguns dados da requisição/tarefa que falhou, bem como todos os logs vinculados, e o traceback. + +Por isso para aproveitar ao máximo o report de erros, **sempre utilize** o logger vindo da função de utilidade `get_logger` disponível no módulo `app.logging.utils`. Isso garante que todos os logs estejam disponíveis nos reports de erros. + +É possível criar uma variável a nível de módulo, como no exemplo abaixo: +```python +from app.logging.utils import get_logger + +LOGGER = get_logger(__name__) + +def some_service(): + logger = LOGGER.new(foo="bar") +``` + +Ou por função: +```python +from app.logging.utils import get_logger + +def some_service(): + logger = get_logger(__name__, foo="bar") +``` + +Perceba que é possível passar variáveis de contexto, isso facilita o debug em casos de erro. Isso é possível por que por baixo dos panos estamos utilizando a lib [struclog](https://www.structlog.org/) com algumas modificações importantes. + +Utilizamos [variáveis de contexto](https://docs.python.org/3/library/contextvars.html) para armazenar todas as chamadas de logs que se encaixam nos filtros de nível (level) de logging. + +* A cada requisição essas chamadas de logs que ficaram armazenadas na memória são resetadas por um [middleware](./src/app/middlewares/log.py). +* A cada tarefa recebida essas chamadas de logs que ficaram armazenadas na memórias são resetadas por um [signal](./src/app/celery/app.py). + + > Isso garante que apenas as chamadas de logs da requisição/tarefa atual sejam reportados (ContextVars são thread-safe). + +Portanto, para configurar o report de erros, siga os seguintes passos: + +* Defina o valor da variável de ambiente `SEND_ERROR_REPORT_ON_FAILURES` para um valor verdadeiro (`1`, `y`, `Yes`) +* Defina o valor da variável de ambiente `MESSAGING_EXTERNAL_SERVICE_BACKEND` para o fornecedor de preferência (atualmente apenas o `discord` pode ser utilizado em produção). + +De acordo com cada fornecedor, será necessário seguir passos diferentes. Abaixo estão os guias para cada um dos fornecedores. + +* `discord`: Será necessário [criar uma conta de BOT](https://discord.com/developers/docs/getting-started) no e convidá-lo ao servidor que serão enviadas as mensagens. Após a criação da conta, será necessário que você inclua o Token de autenticação do Bot na variável de ambiente `MESSAGING_EXTERNAL_SERVICE_DISCORD_OAUTH_TOKEN`, **não prefixe** esta variável de ambiente com `Bot`. + +Após a configuração do seu fornecedor de preferência, defina as variáveis de ambiente: + +* `ERROR_REPORT_REQUEST_CHANNEL_ID` Para o ID do canal/usuário que irá receber a mensagem quando uma requisição falhar; +* `ERROR_REPORT_TASK_CHANNEL_ID` Para o ID do canal/usuário que irá receber a mensagem quando uma tarefa falhar; + + +Por último tenha certeza de que a configuração `DEBUG` está desativada (`False`), essa configuração é definida pela variável de ambiente `DJANGO_DEBUG`. + +Opcionalmente é possível definir o idioma de envio dos reports de erro através da variável de ambiente: `SEND_ERROR_REPORT_ON_LANGUAGE`. + +Após tudo configurado, as mensagem irão se parecer com isto. + +Falha em uma requisição: +![Falha requisição](docs/request_failed_error_report.png) + +Falha em uma tarefa: +![Falha tarefa](docs/task_failed_error_report.png) + ## APIs As APIs são uma das portas de entrada para a aplicação, mas não devem ser mais do que isso. Portanto toda aqui não veremos quase nenhuma regra de negócio. diff --git a/docs/request_failed_error_report.png b/docs/request_failed_error_report.png new file mode 100644 index 0000000000000000000000000000000000000000..e910c4a02ab77d3b3819f64e3bf2025d3acfaccb GIT binary patch literal 63458 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 V=1WEf`Fz(dEv_I|EUN$Qe*yN6GNAwf literal 0 HcmV?d00001 diff --git a/docs/task_failed_error_report.png b/docs/task_failed_error_report.png new file mode 100644 index 0000000000000000000000000000000000000000..416fc78dc22cd2686495a5c7cc3db11fb3cb5578 GIT binary patch literal 72161 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 z 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 literal 0 HcmV?d00001 diff --git a/local.yml b/local.yml index 586d506..656920c 100644 --- a/local.yml +++ b/local.yml @@ -62,7 +62,7 @@ services: celery-worker: <<: *django - command: python -m celery -A app worker -P solo --concurrency 1 --events + command: python -m celery -A app worker -P solo --concurrency 1 --events -l ${CELERY_WORKER_LOGGING_LEVEL:-INFO} ports: [] mailpit: diff --git a/locale/pt_BR/LC_MESSAGES/django.po b/locale/pt_BR/LC_MESSAGES/django.po index 906c968..808c022 100644 --- a/locale/pt_BR/LC_MESSAGES/django.po +++ b/locale/pt_BR/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-09-25 12:38+0000\n" +"POT-Creation-Date: 2023-09-27 18:28+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -18,189 +18,228 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" -#: src/app/consts/push_notification.py:20 +#: src/app/consts/push_notification.py:21 msgid "Created" msgstr "Criado" -#: src/app/consts/push_notification.py:21 +#: src/app/consts/push_notification.py:22 msgid "Enqueued" msgstr "Na fila" -#: src/app/consts/push_notification.py:22 +#: src/app/consts/push_notification.py:23 msgid "Sent" msgstr "Enviado(a)" -#: src/app/consts/push_notification.py:23 +#: src/app/consts/push_notification.py:24 msgid "Delivered" msgstr "Entregue" -#: src/app/consts/push_notification.py:24 +#: src/app/consts/push_notification.py:25 msgid "Read" msgstr "Lido(a)" -#: src/app/consts/push_notification.py:25 +#: src/app/consts/push_notification.py:26 msgid "Failed" msgstr "Falhou" -#: src/app/consts/push_notification.py:42 +#: src/app/consts/push_notification.py:43 msgid "Device not registered" msgstr "Dispositivo não registrado" -#: src/app/consts/push_notification.py:43 +#: src/app/consts/push_notification.py:44 msgid "Message too big" msgstr "Mensagem muito grande" -#: src/app/consts/push_notification.py:44 +#: src/app/consts/push_notification.py:45 msgid "Message rate exceeded" msgstr "Limite de mensagens excedido" -#: src/app/consts/push_notification.py:45 +#: src/app/consts/push_notification.py:46 msgid "Mismatch sender ID" msgstr "ID remetente não confere" -#: src/app/consts/push_notification.py:46 +#: src/app/consts/push_notification.py:47 msgid "Invalid credentials" msgstr "Credenciais inválidas" -#: src/app/consts/push_notification.py:47 +#: src/app/consts/push_notification.py:48 msgid "Not opted-in" msgstr "Não permitiu" -#: src/app/consts/push_notification.py:48 +#: src/app/consts/push_notification.py:49 msgid "Too many delivery attempts" msgstr "Muitas tentativas de entrega" -#: src/app/consts/push_notification.py:57 +#: src/app/consts/push_notification.py:58 msgid "Internal communication" msgstr "Comunicação interna" -#: src/app/forms/fields/phone.py:37 +#: src/app/exceptions.py:11 +msgid "Unexpected failure" +msgstr "" + +#: src/app/forms/fields/phone.py:38 #, python-format msgid "Invalid phone number. Original error message was: %s" msgstr "Número telefone inválido. Mensagem de erro original: %s" -#: src/app/models/base.py:14 +#: src/app/models/base.py:13 +msgid "id" +msgstr "id" + +#: src/app/models/base.py:91 msgid "created at" msgstr "criado em" -#: src/app/models/base.py:17 +#: src/app/models/base.py:94 msgid "updated at" msgstr "atualizado em" -#: src/app/settings/conf.py:134 +#: src/app/services.py:60 +msgid "Request failed at" +msgstr "Requisição falhou em" + +#: src/app/services.py:63 src/app/services.py:92 +msgid "Exception class" +msgstr "Classe exceção" + +#: src/app/services.py:64 src/app/services.py:93 +msgid "More information available on the attached logs/traceback" +msgstr "Mais informações disponíveis nos logs/traceback anexados" + +#: src/app/services.py:88 +msgid "Task failed" +msgstr "Tarefa falhou" + +#: src/app/services.py:89 +msgid "Task id" +msgstr "Id tarefa" + +#: src/app/services.py:90 +msgid "Task args" +msgstr "Args tarefa" + +#: src/app/services.py:91 +msgid "Task kwargs" +msgstr "Kwargs tarefa" + +#: src/app/settings/conf.py:135 msgid "Brazilian Portuguese" msgstr "Português Brasileiro" -#: src/app/settings/conf.py:135 +#: src/app/settings/conf.py:136 msgid "English" msgstr "Inglês" -#: src/app/validators/br/doc.py:28 +#: src/app/validators/br/doc.py:33 msgid "Invalid Certificate" msgstr "certificado inválido" -#: src/app/validators/br/doc.py:35 +#: src/app/validators/br/doc.py:40 msgid "Invalid CNH" msgstr "CNH inválida" -#: src/app/validators/br/doc.py:42 +#: src/app/validators/br/doc.py:47 msgid "Invalid CNPJ" msgstr "CNPJ inválido" -#: src/app/validators/br/doc.py:49 +#: src/app/validators/br/doc.py:54 msgid "Invalid CNS" msgstr "CNS inválido" -#: src/app/validators/br/doc.py:56 +#: src/app/validators/br/doc.py:61 msgid "Invalid CPF" msgstr "CPF inválido" -#: src/app/validators/br/doc.py:63 +#: src/app/validators/br/doc.py:68 msgid "Invalid CPF/CNPJ" msgstr "CPF/CNPJ inválido" -#: src/app/validators/br/doc.py:73 +#: src/app/validators/br/doc.py:78 msgid "Invalid PIS" msgstr "PIS inválido" -#: src/app/validators/br/doc.py:80 +#: src/app/validators/br/doc.py:85 msgid "Invalid RENAVAM" msgstr "RENAVAM inválido" -#: src/app/validators/br/doc.py:87 +#: src/app/validators/br/doc.py:92 msgid "Invalid Voter Registration" msgstr "Título Eleitoral inválido" -#: src/push_notifications/admin.py:47 src/push_notifications/models.py:40 +#: src/push_notifications/admin.py:48 msgid "Title" msgstr "Título" -#: src/push_notifications/admin.py:59 +#: src/push_notifications/admin.py:60 msgid "Failure reason" msgstr "Motivo de falha" -#: src/push_notifications/admin.py:72 +#: src/push_notifications/admin.py:73 msgid "Delivery" msgstr "Entrega" -#: src/push_notifications/admin.py:75 src/users/admin.py:43 +#: src/push_notifications/admin.py:76 src/users/admin.py:43 msgid "Metadata" msgstr "Meta-dados" -#: src/push_notifications/apps.py:8 src/push_notifications/models.py:105 +#: src/push_notifications/apps.py:8 msgid "Push Notification" msgstr "Notificação Push" -#: src/push_notifications/apps.py:9 src/push_notifications/models.py:106 +#: src/push_notifications/apps.py:9 msgid "Push Notifications" msgstr "Notificações Push" -#: src/push_notifications/models.py:17 src/users/apps.py:8 -#: src/users/models.py:67 -msgid "User" -msgstr "Usuário" +#: src/push_notifications/models.py:17 src/users/models.py:74 +msgid "user" +msgstr "usuário" #: src/push_notifications/models.py:35 -msgid "Kind" -msgstr "Espécie" +msgid "kind" +msgstr "espécie" #: src/push_notifications/models.py:36 msgid "The kind of notification" msgstr "A espécie de notificação" #: src/push_notifications/models.py:41 +msgid "title" +msgstr "título" + +#: src/push_notifications/models.py:42 msgid "This is the text that shows on the top of the notification" msgstr "Este é o texto que aparece no topo da notificação" -#: src/push_notifications/models.py:45 -msgid "Description" -msgstr "Descrição" - #: src/push_notifications/models.py:46 +msgid "description" +msgstr "descrição" + +#: src/push_notifications/models.py:47 msgid "This is the text that contains the details of the notification" msgstr "Este é o texto que contém os detalhes da notificação" -#: src/push_notifications/models.py:50 -msgid "Additional data" -msgstr "Dados adicionais" - #: src/push_notifications/models.py:51 +msgid "additional data" +msgstr "dados adicionais" + +#: src/push_notifications/models.py:52 msgid "The additional data that is sent with the notification" msgstr "Os dados adicionais enviados com esta notificação" -#: src/push_notifications/models.py:55 -msgid "Status" -msgstr "Situação" - #: src/push_notifications/models.py:56 +msgid "status" +msgstr "situação" + +#: src/push_notifications/models.py:57 msgid "The current status of this notification" msgstr "A situação atual desta notificação" -#: src/push_notifications/models.py:60 -msgid "Receipt ID" -msgstr "ID Recibo" - #: src/push_notifications/models.py:62 +msgid "receipt ID" +msgstr "ID recibo" + +#: src/push_notifications/models.py:64 msgid "" "The notification service ID for this notification, with this receipt ID we " "can check if the message was delivered" @@ -208,104 +247,124 @@ msgstr "" "O ID da notificação no serviço de notificação, com este ID do recibo podemos " "verificar se a mensagem foi entregue" -#: src/push_notifications/models.py:69 -msgid "Delivery attempts" -msgstr "Tentativas de entrega" +#: src/push_notifications/models.py:72 +msgid "delivery attempts" +msgstr "tentativas de entrega" -#: src/push_notifications/models.py:70 +#: src/push_notifications/models.py:73 msgid "How many times we tried to deliver this notification" msgstr "Quantas vezes tentamos entregar esta notificação" -#: src/push_notifications/models.py:75 -msgid "Failure kind" -msgstr "Espécie falha" +#: src/push_notifications/models.py:78 +msgid "failure kind" +msgstr "espécie falha" -#: src/push_notifications/models.py:76 +#: src/push_notifications/models.py:79 msgid "When the notification fails this was the reason provided" msgstr "Quando esta notificação falhou esse o motivo fornecido" -#: src/push_notifications/models.py:83 -msgid "Failure message" -msgstr "Mensagem de falha" +#: src/push_notifications/models.py:86 +msgid "failure message" +msgstr "mensagem de falha" -#: src/push_notifications/models.py:84 +#: src/push_notifications/models.py:87 msgid "The message provided of the cause of the failure" msgstr "A mensagem fornecida com a causa da falha" -#: src/push_notifications/models.py:90 -msgid "Read at" -msgstr "Lido(a) em" +#: src/push_notifications/models.py:93 +msgid "read at" +msgstr "lido(a) em" -#: src/push_notifications/models.py:91 +#: src/push_notifications/models.py:94 msgid "" "The exact time that this notification was marked as read by the end-user" msgstr "" "O momento exato que esta notificação foi marcada como lida pelo usuário final" -#: src/push_notifications/models.py:96 -msgid "Delivery confirmation received at" -msgstr "Confirmação de entrega recebida em" +#: src/push_notifications/models.py:99 +msgid "delivery confirmation received at" +msgstr "confirmação de entrega recebida em" -#: src/push_notifications/models.py:98 +#: src/push_notifications/models.py:101 msgid "" "When the provider of this notification confirmed the delivery of this " "notification" msgstr "" "Quando o fornecedor desta notificação confirmou a entrega desta notificação" +#: src/push_notifications/models.py:108 +msgid "push notification" +msgstr "notificação Push" + +#: src/push_notifications/models.py:109 +msgid "push notifications" +msgstr "notificações Push" + #: src/users/admin.py:32 msgid "Permissions" msgstr "Permissões" -#: src/users/api/v1/serializers.py:17 -msgid "Unable to login with the given credentials" -msgstr "Impossível logar com as credenciais informadas" +#: src/users/apps.py:8 +msgid "User" +msgstr "Usuário" -#: src/users/apps.py:9 src/users/models.py:68 +#: src/users/apps.py:9 msgid "Users" msgstr "Usuários" #: src/users/models.py:30 -msgid "Email address" -msgstr "Endereço email" +msgid "email address" +msgstr "endereço email" #: src/users/models.py:31 -msgid "Full name" -msgstr "Nome completo" +msgid "full name" +msgstr "nome completo" -#: src/users/models.py:35 -msgid "Is active" +#: src/users/models.py:33 +msgid "notification token" +msgstr "token notificação" + +#: src/users/models.py:34 +msgid "The token used to send push notifications to the user's phone" +msgstr "O token utilizado para enviar notificações push ao telefone do usuário" + +#: src/users/models.py:42 +msgid "is active" msgstr "Está ativo" -#: src/users/models.py:36 +#: src/users/models.py:43 msgid "Inactive users can't login. Use this instead of deleting the user." msgstr "" "Usuário inativos não podem fazer login. Use isto em vez de excluir o usuário." -#: src/users/models.py:40 -msgid "Is staff" -msgstr "É da equipe interna" +#: src/users/models.py:47 +msgid "is staff" +msgstr "é da equipe interna" -#: src/users/models.py:41 +#: src/users/models.py:48 msgid "Only staff users can access the admin" msgstr "Apenas usuários da equipe interna podem acessar o admin" -#: src/users/models.py:45 -msgid "Is admin" -msgstr "É super usuário" +#: src/users/models.py:52 +msgid "is admin" +msgstr "é super usuário" -#: src/users/models.py:46 +#: src/users/models.py:53 msgid "Super users have all permissions" msgstr "Super usuários tem todas as permissões" -#: src/users/models.py:51 -msgid "Date joined" -msgstr "Data inscrição" +#: src/users/models.py:58 +msgid "date joined" +msgstr "data inscrição" + +#: src/users/models.py:75 +msgid "users" +msgstr "usuários" -#: src/users/models.py:77 -msgid "User Group" -msgstr "Grupo de Usuário" +#: src/users/models.py:84 +msgid "user group" +msgstr "grupo de Usuário" -#: src/users/models.py:78 -msgid "User Groups" -msgstr "Grupo de Usuários" +#: src/users/models.py:85 +msgid "user groups" +msgstr "grupo de Usuários" diff --git a/pdm.lock b/pdm.lock index 6316f99..f2187d7 100644 --- a/pdm.lock +++ b/pdm.lock @@ -687,6 +687,12 @@ dependencies = [ "pbr!=2.1.0,>=2.0.0", ] +[[package]] +name = "structlog" +version = "23.1.0" +requires_python = ">=3.7" +summary = "Structured Logging for Python" + [[package]] name = "types-pytz" version = "2023.3.1.1" @@ -774,7 +780,7 @@ dependencies = [ lock_version = "4.2" cross_platform = true groups = ["default", "dev"] -content_hash = "sha256:273a201e7d0605448c4a3616e84c594624fa0f089a62565e41bfe51ae3902a83" +content_hash = "sha256:5a28bdf12fe80a05da40a431ffe6ff468e8cc2cb45189a735d9b0d923f0c0c46" [metadata.files] "amqp 5.1.1" = [ @@ -1514,6 +1520,10 @@ content_hash = "sha256:273a201e7d0605448c4a3616e84c594624fa0f089a62565e41bfe51ae {url = "https://files.pythonhosted.org/packages/4b/68/e739fd061b0aba464bef8e8be48428b2aabbfb3f2f8f2f8ca257363ee6b2/stevedore-5.1.0-py3-none-any.whl", hash = "sha256:8cc040628f3cea5d7128f2e76cf486b2251a4e543c7b938f58d9a377f6694a2d"}, {url = "https://files.pythonhosted.org/packages/ac/d6/77387d3fc81f07bc8877e6f29507bd7943569093583b0a07b28cfa286780/stevedore-5.1.0.tar.gz", hash = "sha256:a54534acf9b89bc7ed264807013b505bf07f74dbe4bcfa37d32bd063870b087c"}, ] +"structlog 23.1.0" = [ + {url = "https://files.pythonhosted.org/packages/0c/b2/0c0951c78f3f59ce44e93cb9b2140d305a00bb8262532041c702d4d4300a/structlog-23.1.0-py3-none-any.whl", hash = "sha256:79b9e68e48b54e373441e130fa447944e6f87a05b35de23138e475c05d0f7e0e"}, + {url = "https://files.pythonhosted.org/packages/9e/c4/688d14600f3a8afa31816ac95220f2548648e292c3ff2262057aa51ac2fb/structlog-23.1.0.tar.gz", hash = "sha256:270d681dd7d163c11ba500bc914b2472d2b50a8ef00faa999ded5ff83a2f906b"}, +] "types-pytz 2023.3.1.1" = [ {url = "https://files.pythonhosted.org/packages/79/4f/58c28f50233612d9890cc2b068aee977ef3f7d6434ef4debf98162e34152/types_pytz-2023.3.1.1-py3-none-any.whl", hash = "sha256:1999a123a3dc0e39a2ef6d19f3f8584211de9e6a77fe7a0259f04a524e90a5cf"}, {url = "https://files.pythonhosted.org/packages/a7/33/6f8feb17652548d68f0bab14c7f810419ffc43bd30792d54a89289ac2b6f/types-pytz-2023.3.1.1.tar.gz", hash = "sha256:cc23d0192cd49c8f6bba44ee0c81e4586a8f30204970fc0894d209a6b08dab9a"}, diff --git a/pyproject.toml b/pyproject.toml index 58fbfec..d093d77 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -93,6 +93,7 @@ dependencies = [ "django-extensions==3.2.3", "werkzeug==2.3.7", "django-filter==23.3", + "structlog==23.1.0", ] requires-python = ">=3.11" license = {text = "MIT"} diff --git a/src/app/celery/app.py b/src/app/celery/app.py index f59edd9..ecb56d9 100644 --- a/src/app/celery/app.py +++ b/src/app/celery/app.py @@ -1,7 +1,7 @@ import os from datetime import timedelta -from celery import Celery +from celery import Celery, signals from django.conf import settings os.environ.setdefault("DJANGO_SETTINGS_MODULE", "app.settings.conf") @@ -36,3 +36,23 @@ app.autodiscover_tasks(["push_notifications"]) app.conf.update(**CELERY_CONFIG) + + +@signals.task_prerun.connect +def bind_contextvars_before_task_run(sender, task_id, task, args, kwargs, **_): + import structlog + + from app.logging.utils import _log_events + + _log_events.set([]) + structlog.contextvars.bind_contextvars(task_id=task_id) + + +@signals.task_failure.connect +def report_error_after_task_failure(sender, **kwargs): + from app import services + + if settings.SEND_ERROR_REPORT_ON_FAILURES: + services.send_task_error_report( + task=sender, exception=kwargs["exception"], einfo=kwargs["einfo"] + ) diff --git a/src/app/ext/messaging/__init__.py b/src/app/ext/messaging/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/app/ext/messaging/abc.py b/src/app/ext/messaging/abc.py new file mode 100644 index 0000000..a9117c5 --- /dev/null +++ b/src/app/ext/messaging/abc.py @@ -0,0 +1,98 @@ +from dataclasses import dataclass +from io import StringIO +from typing import TYPE_CHECKING, Self, Sequence, Union + +from django.conf import settings + +from app.ext.abc import ExternalService + +if TYPE_CHECKING: + from django_stubs_ext import StrOrPromise + + +@dataclass +class EmbedFile: + io: StringIO + filename: str + content_type: str + + +class _TextFormat: + """Base class for formatting text, subclasses may provide the `wrapper_start` + and `wrapper_end` attributes, that will be used to construct the desired formatting. + The formatting wrappers don't have any language specific formatting, they need to be + handled by each messaging service, in order to correctly format the message on that + platform. + """ + + wrapper_start: str + wrapper_end: str + + def __init__(self, value: "StrOrPromise"): + self.value = value + + def __str__(self): + return "{}{}{}".format( + self.wrapper_start, + str(self.value), # force evaluation + self.wrapper_end, + ) + + def __add__(self, other: Union["StrOrPromise", Self]) -> str: + return str(self) + str(other) + + def __radd__(self, other: Union["StrOrPromise", Self]) -> str: + return str(other) + str(self) + + +class TextBold(_TextFormat): + wrapper_start = "<>" + wrapper_end = "<>" + + +class TextItalic(_TextFormat): + wrapper_start = "<>" + wrapper_end = "<>" + + +class TextCodeInline(_TextFormat): + wrapper_start = "" + wrapper_end = "" + + +class TextCodeBlock(_TextFormat): + wrapper_start = "<>" + wrapper_end = "<" + + +class Message: + """Composable message that can be composable by multiple segments of text formatting. + The contents of the message will be joined by the given `join_char`. + """ + + def __init__(self, *contents: Union[_TextFormat, "StrOrPromise"], join_char: str = "\n"): + self.contents = contents + self.join_char = join_char + + def __str__(self): + return self.join_char.join(str(c) for c in self.contents) + + +def messaging_external_service_loader() -> "MessagingExternalService": + from .backends.discord import DiscordMessagingExternalService + from .backends.stdout import DevSTDOutMessagingExternalService + + backends = { + "dev.stdout": DevSTDOutMessagingExternalService, + "discord": DiscordMessagingExternalService, + } + return backends[settings.MESSAGING_EXTERNAL_SERVICE_BACKEND]() + + +class MessagingExternalService(ExternalService): + service_loader = messaging_external_service_loader + + def send(self, *, to: str, message: Message, files: Sequence[EmbedFile]) -> None: + """Sends a message `to` someone or something. Subclasses may handle the `message` + formatting and the `files` that should be sent with the message.""" + raise NotImplementedError("Missing implementation for method send") diff --git a/src/app/ext/messaging/backends/__init__.py b/src/app/ext/messaging/backends/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/app/ext/messaging/backends/discord.py b/src/app/ext/messaging/backends/discord.py new file mode 100644 index 0000000..795937f --- /dev/null +++ b/src/app/ext/messaging/backends/discord.py @@ -0,0 +1,71 @@ +import json +from io import StringIO +from typing import Any, Sequence + +import requests +from django.conf import settings + +from app.ext.messaging.abc import ( + EmbedFile, + Message, + MessagingExternalService, + TextBold, + TextCodeBlock, + TextCodeInline, + TextItalic, +) + +format_replacers = { + TextBold.wrapper_start: "**", + TextBold.wrapper_end: "**", + TextCodeInline.wrapper_start: "`", + TextCodeInline.wrapper_end: "`", + TextCodeBlock.wrapper_start: "```python\n", + TextCodeBlock.wrapper_end: "```", + TextItalic.wrapper_start: "*", + TextItalic.wrapper_end: "*", +} + + +class DiscordMessagingExternalService(MessagingExternalService): + suitable_for_production = True + + def __init__(self): + self.oauth_token = settings.MESSAGING_EXTERNAL_SERVICE_DISCORD_OAUTH_TOKEN + + def send(self, *, to: str, message: Message, files: Sequence[EmbedFile]): + formatted_message = str(message) + for to_replace, replaced in format_replacers.items(): + formatted_message = formatted_message.replace(to_replace, replaced) + + embed_files: list[tuple[str, tuple[str, StringIO, str]]] = [] + attachments = [] + for n, file in enumerate(files): + file.io.seek(0) + embed_files.append( + ( + f"files[{n}]", + (file.filename, file.io, file.content_type), + ) + ) + attachments.append({"id": n, "filename": file.filename}) + + DISCORD_MESSAGE_LIMIT = 2000 + if len(formatted_message) > DISCORD_MESSAGE_LIMIT: + formatted_message = formatted_message[:DISCORD_MESSAGE_LIMIT] + json_payload: dict[str, Any] = {"content": formatted_message} + if attachments: + json_payload["attachments"] = attachments + + try: + response = requests.post( + url=f"https://discord.com/api/channels/{to}/messages", + headers={"Authorization": f"Bot {self.oauth_token}"}, + data={"payload_json": json.dumps(json_payload)}, + files=embed_files or None, + timeout=5, + ) + response.raise_for_status() + except (requests.Timeout, requests.HTTPError) as e: + print("Failed to send message", e) + return diff --git a/src/app/ext/messaging/backends/stdout.py b/src/app/ext/messaging/backends/stdout.py new file mode 100644 index 0000000..31e5cef --- /dev/null +++ b/src/app/ext/messaging/backends/stdout.py @@ -0,0 +1,41 @@ +import json +from io import StringIO +from typing import Any, Sequence + +import requests +from django.conf import settings + +from app.ext.messaging.abc import ( + EmbedFile, + Message, + MessagingExternalService, + TextBold, + TextCodeBlock, + TextCodeInline, + TextItalic, +) + +format_replacers = { + TextBold.wrapper_start: "**", + TextBold.wrapper_end: "**", + TextCodeInline.wrapper_start: "`", + TextCodeInline.wrapper_end: "`", + TextCodeBlock.wrapper_start: "```python\n", + TextCodeBlock.wrapper_end: "```", + TextItalic.wrapper_start: "*", + TextItalic.wrapper_end: "*", +} + + +class DevSTDOutMessagingExternalService(MessagingExternalService): + suitable_for_production = False + + def send(self, *, to: str, message: Message, files: Sequence[EmbedFile]): + formatted_message = str(message) + for to_replace, replaced in format_replacers.items(): + formatted_message = formatted_message.replace(to_replace, replaced) + + print("Received messaging send request") + print("To:", to) + print("Message:", formatted_message) + print("Files:", files) diff --git a/src/app/logging/__init__.py b/src/app/logging/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/app/logging/types.py b/src/app/logging/types.py new file mode 100644 index 0000000..01432aa --- /dev/null +++ b/src/app/logging/types.py @@ -0,0 +1,79 @@ +from typing import Protocol, Self + +import structlog +from django.utils import timezone + + +class StructLogger(Protocol): + events: list[str] + + def bind(self, **new_values) -> Self: + ... + + def new(self, **new_values) -> Self: + ... + + def unbind(self, **values) -> Self: + ... + + def debug(self, msg, *args, **kwargs) -> None: + ... + + def info(self, msg, *args, **kwargs) -> None: + ... + + def warning(self, msg, *args, **kwargs) -> None: + ... + + def error(self, msg, *args, **kwargs) -> None: + ... + + def critical(self, msg, *args, **kwargs) -> None: + ... + + def exception(self, msg, *args, **kwargs) -> None: + ... + + +class BoundLogCollector(structlog.stdlib.BoundLogger): + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + + def collect_and_proxy_to_logger(self, method_name: str, event: str, *event_args, **event_kw): + from .utils import _log_events + + try: + args, kw = self._process_event(method_name, event, event_kw) + event_data = args[0].copy() + getattr(self._logger, method_name)(*args, **kw) + except structlog.DropEvent: + return None + data = { + "timestamp": timezone.now().isoformat(), + "context": self._context, + **event_data, + } + _log_events.get().append(data) + + def debug(self, event=None, *args, **kwargs): + return self.collect_and_proxy_to_logger("debug", event, *args, **kwargs) + + def info(self, event=None, *args, **kwargs): + return self.collect_and_proxy_to_logger("info", event, *args, **kwargs) + + def warning(self, event=None, *args, **kwargs): + return self.collect_and_proxy_to_logger("warning", event, *args, **kwargs) + + warn = warning + + def error(self, event=None, *args, **kwargs): + return self.collect_and_proxy_to_logger("error", event, *args, **kwargs) + + def critical(self, event=None, *args, **kwargs): + return self.collect_and_proxy_to_logger("critical", event, *args, **kwargs) + + fatal = critical + + def exception(self, event=None, *args, **kwargs): + kwargs.setdefault("exc_info", True) + return self.collect_and_proxy_to_logger("error", event, *args, **kwargs) diff --git a/src/app/logging/utils.py b/src/app/logging/utils.py new file mode 100644 index 0000000..6ffe73e --- /dev/null +++ b/src/app/logging/utils.py @@ -0,0 +1,28 @@ +from contextvars import ContextVar +from typing import Any + +from .types import BoundLogCollector, StructLogger + +# This context-var is used by middlewares/signals +_log_events: ContextVar[list[dict[str, Any]]] = ContextVar("_log_events") + + +def get_logger(name: str, **initial_context) -> StructLogger: + # import this here to not polute the import auto-complete + import structlog + from celery.utils.log import get_task_logger + + logger = structlog.wrap_logger( + get_task_logger(name), + processors=[ + structlog.contextvars.merge_contextvars, + structlog.stdlib.add_logger_name, + structlog.stdlib.add_log_level, + structlog.stdlib.filter_by_level, + structlog.processors.UnicodeDecoder(), + structlog.stdlib.ProcessorFormatter.wrap_for_formatter, + ], + wrapper_class=BoundLogCollector, # type: ignore + **initial_context, + ) + return logger diff --git a/src/app/middlewares/log.py b/src/app/middlewares/log.py new file mode 100644 index 0000000..6b53c3f --- /dev/null +++ b/src/app/middlewares/log.py @@ -0,0 +1,21 @@ +import structlog +from django.conf import settings +from django.http import HttpRequest + +from app import services +from app.logging.utils import _log_events + + +class LogContextMiddleware: + def __init__(self, get_response) -> None: + self.get_response = get_response + + def __call__(self, request: HttpRequest): + _log_events.set([]) + if request.user.is_authenticated: + structlog.contextvars.bind_contextvars(user_id=request.user.id) + return self.get_response(request) + + def process_exception(self, request, exception): + if settings.SEND_ERROR_REPORT_ON_FAILURES: + services.send_request_error_report(request=request, exception=exception) diff --git a/src/app/services.py b/src/app/services.py new file mode 100644 index 0000000..b97f808 --- /dev/null +++ b/src/app/services.py @@ -0,0 +1,97 @@ +import json +import traceback +from io import StringIO + +from billiard.einfo import ExceptionInfo +from django.conf import settings +from django.http import HttpRequest +from django.utils import translation +from django.utils.translation import gettext_lazy as _ + +from app.celery.decorators import BaseTask +from app.ext import di +from app.ext.messaging.abc import ( + EmbedFile, + Message, + MessagingExternalService, + TextBold, + TextCodeInline, + TextItalic, +) +from app.logging.utils import _log_events + + +def _get_embed_files(formatted_traceback: str | None = None) -> list[EmbedFile]: + tb: str = formatted_traceback or traceback.format_exc() + traceback_file = EmbedFile(io=StringIO(tb), filename="traceback.py", content_type="text/py") + embed_files = [traceback_file] + try: + logs = _log_events.get() + except LookupError: + logs = [] + + if logs: + embed_files.append( + EmbedFile( + io=StringIO(json.dumps(logs, ensure_ascii=False, indent=2)), + filename="logs.json", + content_type="application/json", + ) + ) + return embed_files + + +@di.inject_service_at_runtime(MessagingExternalService) +def send_request_error_report( + *, + request: HttpRequest, + exception: Exception, + messaging_service: MessagingExternalService = MessagingExternalService(), +): + """Sends a error report over a messaging service. + This is triggered after a request fails, by a middleware. + This report is only sent if `DEBUG=False`. + """ + if settings.DEBUG: + return + + with translation.override(settings.SEND_ERROR_REPORT_ON_LANGUAGE, deactivate=True): + message = Message( + TextBold(_("Request failed at")) + + ": " + + TextCodeInline(f"{request.method} {request.path}"), + TextBold(_("Exception class")) + ": " + TextCodeInline(exception.__class__.__name__), + TextItalic(_("More information available on the attached logs/traceback")), + ) + receiver = settings.ERROR_REPORT_REQUEST_CHANNEL_ID + embed_files = _get_embed_files() + messaging_service.send(to=receiver, message=message, files=embed_files) + + +@di.inject_service_at_runtime(MessagingExternalService) +def send_task_error_report( + *, + task: BaseTask, + exception: Exception, + einfo: ExceptionInfo, + messaging_service: MessagingExternalService = MessagingExternalService(), +): + """Sends a error report over a messaging service. + This is triggered after a celery task fails, by a signal. + This report is only sent if `DEBUG=False`. + """ + if settings.DEBUG: + return + + with translation.override(settings.SEND_ERROR_REPORT_ON_LANGUAGE, deactivate=True): + message = Message( + TextBold(_("Task failed")) + ": " + TextCodeInline(task.name), + TextBold(_("Task id")) + ": " + TextCodeInline(task.request.id), + TextBold(_("Task args")) + ": " + TextCodeInline(task.request.args), + TextBold(_("Task kwargs")) + ": " + TextCodeInline(task.request.kwargs), + TextBold(_("Exception class")) + ": " + TextCodeInline(exception.__class__.__name__), + TextItalic(_("More information available on the attached logs/traceback")), + ) + receiver = settings.ERROR_REPORT_TASK_CHANNEL_ID + embed_files = _get_embed_files(formatted_traceback=einfo.traceback) + messaging_service.send(to=receiver, message=message, files=embed_files) diff --git a/src/app/settings/conf.py b/src/app/settings/conf.py index 924e677..5ae5ec9 100644 --- a/src/app/settings/conf.py +++ b/src/app/settings/conf.py @@ -95,6 +95,7 @@ "django.middleware.clickjacking.XFrameOptionsMiddleware", "django.middleware.locale.LocaleMiddleware", "app.middlewares.tz.TimezoneMiddleware", + "app.middlewares.log.LogContextMiddleware", ] ROOT_URLCONF: str = "app.urls" TEMPLATES: List[Dict[str, Any]] = [ @@ -204,10 +205,12 @@ } from .external_services.geolocation import * +from .external_services.messaging import * from .external_services.push_notification import * from .external_services.sms import * from .external_services.zipcode import * from .infra.log import * +from .infra.reporting import * from .third_party.celery import * from .third_party.dj_cors_headers import * from .third_party.drf import * diff --git a/src/app/settings/external_services/messaging.py b/src/app/settings/external_services/messaging.py new file mode 100644 index 0000000..f215589 --- /dev/null +++ b/src/app/settings/external_services/messaging.py @@ -0,0 +1,8 @@ +from app.settings.env import env + +MESSAGING_EXTERNAL_SERVICE_BACKEND = env("MESSAGING_EXTERNAL_SERVICE_BACKEND", default="dev.stdout") + +if MESSAGING_EXTERNAL_SERVICE_BACKEND == "discord": + MESSAGING_EXTERNAL_SERVICE_DISCORD_OAUTH_TOKEN = env( + "MESSAGING_EXTERNAL_SERVICE_DISCORD_OAUTH_TOKEN" + ) diff --git a/src/app/settings/infra/reporting.py b/src/app/settings/infra/reporting.py new file mode 100644 index 0000000..5427fb2 --- /dev/null +++ b/src/app/settings/infra/reporting.py @@ -0,0 +1,13 @@ +from app.settings.env import env + +SEND_ERROR_REPORT_ON_FAILURES = env.bool("SEND_ERROR_REPORT_ON_FAILURES", default=False) +SEND_ERROR_REPORT_ON_LANGUAGE = env("SEND_ERROR_REPORT_ON_LANGUAGE", default="en-us") +MESSAGING_EXTERNAL_SERVICE_BACKEND = env("MESSAGING_EXTERNAL_SERVICE_BACKEND", default="dev.stdout") + + +if MESSAGING_EXTERNAL_SERVICE_BACKEND == "dev.stdout": + ERROR_REPORT_REQUEST_CHANNEL_ID = "" + ERROR_REPORT_TASK_CHANNEL_ID = "" +else: + ERROR_REPORT_REQUEST_CHANNEL_ID = env("ERROR_REPORT_REQUEST_CHANNEL_ID") + ERROR_REPORT_TASK_CHANNEL_ID = env("ERROR_REPORT_TASK_CHANNEL_ID") diff --git a/src/push_notifications/services.py b/src/push_notifications/services.py index 088fd49..319c1a2 100644 --- a/src/push_notifications/services.py +++ b/src/push_notifications/services.py @@ -10,6 +10,7 @@ PushReceipt, PushTicket, ) +from app.logging.utils import get_logger from app.models import BaseModel from users.models import User @@ -127,15 +128,28 @@ def push_notification_delivery_failed(notification: models.PushNotification): It expects that failure_kind is populated, meaning that is on the failed status""" from . import tasks + logger = get_logger( + __name__, + notification_id=notification.id, + notification_failure_kind=notification.failure_kind, + user_id=notification.user_id, + delivery_attempts=notification.delivery_attempts, + ) + logger.debug("Push notification delivery failed") + if notification.failure_kind == consts.push_notification.FailureKind.DEVICE_NOT_REGISTERED: # we're recommended to not keep trying sending notifications to non-registered devices + logger.warning("User device is no longer registered, removing his token") user: User = notification.user user.notification_token = None user.save() return if notification.failure_kind == consts.push_notification.FailureKind.MESSAGE_RATE_EXCEEDED: + logger.warning("Looks like we're sending to many messages") + if notification.delivery_attempts > notification.MAX_DELIVERY_ATTEMPTS: + logger.warning(f"Reached {notification.MAX_DELIVERY_ATTEMPTS=} failing") notification.status = consts.push_notification.Status.FAILED notification.failure_kind = ( consts.push_notification.FailureKind.TOO_MANY_DELIVERY_ATTEMPTS @@ -143,16 +157,19 @@ def push_notification_delivery_failed(notification: models.PushNotification): notification.failure_message = "Too many attempts to deliver the notification failed" notification.save() return + logger.warning("Enqueueing message again") notification.status = consts.push_notification.Status.ENQUEUED notification.delivery_attempts += 1 notification.failure_kind = None notification.failure_message = None notification.save() tasks.push_notification_handle_resend.apply_async( - kwargs={"notification_id": notification.id} + kwargs={"notification_id": notification.id}, + countdown=5, ) + return - # TODO: Log that we can't handle this + logger.critical(f"Unable to handle the {notification.failure_kind=}") @di.inject_service_at_runtime(PushNotificationExternalService) @@ -164,6 +181,9 @@ def push_notification_confirm_delivery( """Tries to confirm the delivery of sent notifications that were created after dt - 1 days. This is called periodically by celery""" yesterday = dt - timedelta(days=1) + logger = get_logger(__name__, dt=dt, notification_service=notification_service) + logger.info("Starting to confirm the delivery of push notifications") + notifications = models.PushNotification.objects.filter( status=consts.push_notification.Status.SENT, created_at__date__gte=yesterday.date(), @@ -171,7 +191,9 @@ def push_notification_confirm_delivery( ).select_related("user") if not notifications: # No need to send no tickets to the notification service + logger.info("All good no notifications to confirm delivery") return + logger.debug("Found some notifications to confirm delivery, getting receipts") receipts = notification_service.get_receipts( [notification.push_ticket_id for notification in notifications] # type: ignore ) @@ -179,7 +201,9 @@ def push_notification_confirm_delivery( for notification in notifications: receipt = receipts.get(notification.push_ticket_id) # type: ignore if receipt is None: + logger.warning(f"Unable to find receipt for {notification=}") continue + logger.debug(f"Handling push {receipt=}") push_notification_handle_push_receipt( notification=notification, receipt=receipt, diff --git a/src/push_notifications/tasks.py b/src/push_notifications/tasks.py index 48a96c7..ac7e77c 100644 --- a/src/push_notifications/tasks.py +++ b/src/push_notifications/tasks.py @@ -1,5 +1,3 @@ -import uuid - from django.utils.translation import gettext as _ from app.celery.decorators import BaseTask, task diff --git a/src/users/migrations/0001_initial.py b/src/users/migrations/0001_initial.py index 3f0d513..b149a5e 100644 --- a/src/users/migrations/0001_initial.py +++ b/src/users/migrations/0001_initial.py @@ -55,7 +55,7 @@ class Migration(migrations.Migration): help_text="The token used to send push notifications to the user's phone", max_length=128, null=True, - verbose_name="Notification token", + verbose_name="notification token", ), ), ( diff --git a/src/users/models.py b/src/users/models.py index 5e62e52..06551e1 100644 --- a/src/users/models.py +++ b/src/users/models.py @@ -30,7 +30,7 @@ class User(AbstractBaseUser, PermissionsMixin, BaseModel): email = models.EmailField(_("email address"), unique=True) full_name = models.CharField(_("full name"), max_length=255) notification_token = models.CharField( - verbose_name=_("Notification token"), + verbose_name=_("notification token"), help_text=_("The token used to send push notifications to the user's phone"), max_length=128, null=True, diff --git a/tests/conftest.py b/tests/conftest.py index 9117734..4c29d94 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -23,3 +23,10 @@ def visitor_user(): user.full_clean() user.save() return user + + +@pytest.fixture(autouse=True) +def set_log_events_context(): + from app.logging.utils import _log_events + + _log_events.set([]) diff --git a/tests/test_push_notifications/test_services/test_push_notification_delivery_failed.py b/tests/test_push_notifications/test_services/test_push_notification_delivery_failed.py index 2b4fa1f..165cdda 100644 --- a/tests/test_push_notifications/test_services/test_push_notification_delivery_failed.py +++ b/tests/test_push_notifications/test_services/test_push_notification_delivery_failed.py @@ -73,7 +73,9 @@ def test_push_notification_delivery_failed_dispatches_a_resend_task_when_failure "push_notifications.tasks.push_notification_handle_resend.apply_async" ) services.push_notification_delivery_failed(push_notification) - resend_task.assert_called_once_with(kwargs={"notification_id": push_notification.id}) + resend_task.assert_called_once_with( + kwargs={"notification_id": push_notification.id}, countdown=5 + ) # we're not using refresh_from_db because mypy complains on asserts notification = models.PushNotification.objects.get(pk=push_notification.pk)