feat(rollbar): opcjonalne wyciszenie błędów SMTP per instalacja#678
feat(rollbar): opcjonalne wyciszenie błędów SMTP per instalacja#678mpasternak wants to merge 2 commits into
Conversation
Na bpp.umlub.pl serwer SMTP uczelni odrzuca poświadczenia (535 5.7.3 Authentication unsuccessful) — awaria po stronie administratorów poczty klienta, której nie naprawimy kodem. Efekt w Rollbarze: 60 wystąpień (#1554, #379), rosnące. Wyciszenie jest OPT-IN per instalacja przez DJANGO_BPP_ROLLBAR_IGNORE_SMTP_ERRORS (domyślnie wyłączone), bo na pozostałych instalacjach niedziałająca poczta to realny problem — nie idą powiadomienia o zgłoszeniach publikacji do redaktorów i nikt tego nie zauważa, dopóki ktoś nie zapyta. Mechanizm: exception_level_filters pyrollbara z poziomem "ignored" (rollbar._is_ignored). Wyciszamy CAŁĄ rodzinę smtplib.SMTPException, bo awaria "poczta nie działa" ma wiele wcieleń, nie tylko 535 — ale nic poza nią (ConnectionRefusedError z Redisa czy PBN nadal leci). Budowanie listy filtrów wyodrębnione do django_bpp/rollbar_filters.py jako czysta funkcja — inaczej nie da się tego przetestować bez przeładowywania ustawień Django. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NcAqeqyqBzNEkkVnhpHDaH
Self-review obalił przesłankę, na której zbudowałem ten PR. 1. Twierdziłem, że "każde wystąpienie zakłada osobny item". NIEPRAWDA — sprawdzone w Rollbarze: item #379 ma total_occurrences=59, item #1554 ma 1. Czyli 60 wystąpień to DWA itemy, nie 60; grupowanie działa poprawnie. Drugi item odszczepił się tylko dlatego, że między wystąpieniami poszła podbitka pyrollbara 1.3.0 → 1.4.0, zmieniając hash. To jednak nadal jest argument za wyciszeniem w kodzie, tylko INNY: "mute" w interfejsie Rollbara jest per item i przepada przy zmianie hasha (jak wyżej), a wyciszenie w repo jest trwałe i widoczne w gicie — da się je znaleźć i cofnąć, gdy klient naprawi pocztę. Uzasadnienie przepisane na prawdziwe. 2. Zakres zawężony z całej rodziny smtplib.SMTPException do samego SMTPAuthenticationError. Poprzedni zakres wyciszał SMTPRecipientsRefused (zły adres w NASZEJ bazie) i SMTPSenderRefused (nasza konfiguracja DEFAULT_FROM_EMAIL) — jedno i drugie jest do naprawienia po naszej stronie. Przy okazji: "cała rodzina błędów poczty" i tak było nieosiągalne, bo odmowa połączenia TCP leci jako ConnectionRefusedError, który nie jest podklasą SMTPException. 3. Test "kontraktu z pyrollbarem" celował w rollbar._is_ignored — funkcję, która w pyrollbar 1.4.0 NIE JEST NIGDZIE WYWOŁYWANA (jedyne wystąpienie to jej definicja). Realne tłumienie idzie przez _filtered_level → events.on_exception_info → filters.basic.filter_by_level. Testy jadą teraz prawdziwą ścieżką, z przechwyceniem send_payload. Zweryfikowane mutacją: wyłączenie flagi, rozszerzenie do SMTPException i literówka w poziomie — każde łapane. 4. Zmienna dopisana do .env.example (przełącznik per instalacja, którego nie widać w .env.example, jest dla wdrażającego nieodkrywalny) oraz ostrzeżenie w docstringu, że przy DJANGO_BPP_HOSTNAMES działa na wszystkie uczelnie w procesie. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NcAqeqyqBzNEkkVnhpHDaH
Poprawki po self-review — moje uzasadnienie było fałszyweReview podważył przesłankę tego PR-a i miał rację. Naniesione w 1. „Każde wystąpienie zakłada osobny item" — NIEPRAWDASprawdziłem w Rollbarze: item #379 ma To jednak nadal jest argument za wyciszeniem w kodzie — tylko inny: 2. Zakres zawężony do
|
| mutacja | wynik |
|---|---|
| flaga ignorowana (pusta lista) | 1 failed |
rozszerzenie do SMTPException |
1 failed |
"ignore" zamiast "ignored" |
1 failed |
Stara wersja testów nie wykrywała mutacji „za szeroki zakres".
4. Drobiazgi
- Zmienna dopisana do
.env.example— przełącznik per instalacja, którego tam
nie widać, jest dla wdrażającego nieodkrywalny. - Ostrzeżenie w docstringu: przy
DJANGO_BPP_HOSTNAMES(multi-tenant w jednym
procesie) ustawienie działa na wszystkie uczelnie tego procesu. Dla
bpp.umlub.plto nie problem — payload pokazuje tryb single-host i dedykowany
kontener z własnym workerem.
Świadoma decyzja, mimo zastrzeżenia review
Review argumentuje, żeby PR-a nie mergować, bo wyciszenie usuwa jedyny sygnał,
że redakcja UM Lublin nie dostaje powiadomień o zgłoszeniach publikacji.
To prawda i jest to realna szkoda — payload pokazuje wprost pięć adresów, do
których nie dochodzi poczta.
Zostawiam PR, bo to była świadoma decyzja właściciela produktu: awaria jest
znana, leży po stronie informatyków klienta i jest zgłoszona. Ale odnotowuję
wprost: to nie naprawia poczty i dopóki klient nie odblokuje SMTP-a,
zgłoszenia publikacji będą lądować w bazie niezauważone. Warto wrócić do tej
zmiennej po naprawie i ją usunąć.
Problem
Na
bpp.umlub.plserwer SMTP uczelni odrzuca poświadczenia:To awaria po stronie administratorów poczty klienta — nie naprawimy jej kodem.
W Rollbarze: 60 wystąpień i rośnie
(#1554,
#379).
Rozwiązanie
Wyciszenie opt-in per instalacja, przez
DJANGO_BPP_ROLLBAR_IGNORE_SMTP_ERRORS(domyślnie wyłączone).Domyślne wyłączenie jest tu istotne: na pozostałych instalacjach niedziałająca
poczta to realny problem — nie idą powiadomienia o zgłoszeniach publikacji do
redaktorów i nikt tego nie zauważa, dopóki ktoś nie zapyta. Globalne
wyciszenie zamieniłoby jeden hałaśliwy problem na jeden cichy.
Mechanizm:
exception_level_filterspyrollbara z poziomem"ignored"(
rollbar._is_ignored). Wyciszamy całą rodzinęsmtplib.SMTPException, boawaria „poczta nie działa" ma wiele wcieleń, nie tylko 535 — ale nic poza nią
(
ConnectionRefusedErrorz Redisa czy PBN nadal leci).Budowanie listy filtrów wyodrębnione do
django_bpp/rollbar_filters.pyjakoczysta funkcja — inaczej nie da się tego przetestować bez przeładowywania
ustawień Django.
Jak włączyć na UM Lublin
W konfiguracji deploymentu tej instalacji (
bpp-deploy), w env appserverai celery workera (wyjątek leci z workera —
djcelery_email):Bez tego merge PR-a niczego nie zmienia.
Testy
src/django_bpp/tests/test_rollbar_filters.py— 6 testów:SMTPConnectError,SMTPServerDisconnected),ConnectionRefusedErroraniValueError,settings.ROLLBARfaktycznie zawiera filtry (sama funkcja nic nie da, jeślinikt jej nie zawoła) i domyślnie są puste,
rollbar._is_ignoredhonoruje nasz format krotek —bez tego literówka
"ignore"zamiast"ignored"przeszłaby niezauważona.Testy napisane po implementacji (mój błąd procesowy), więc zweryfikowałem je
mutacją kodu produkcyjnego — wszystkie trzy mutacje są łapane:
"ignore"zamiast"ignored"Exceptionzamiastsmtplib.SMTPExceptionDodatkowo sprawdzone end-to-end: z
DJANGO_BPP_ROLLBAR_IGNORE_SMTP_ERRORS=1settings.ROLLBAR["exception_level_filters"]to[(<class 'smtplib.SMTPException'>, 'ignored')].Uwaga
To nie naprawia poczty — powiadomienia o zgłoszeniach publikacji nadal nie
docierają do redaktorów UM Lublin. To wyłącznie decyzja, żeby nie raportować
awarii, której nie kontrolujemy. Sprawa SMTP wymaga zgłoszenia po stronie
klienta.
🤖 Generated with Claude Code
https://claude.ai/code/session_01NcAqeqyqBzNEkkVnhpHDaH