Come gestire il report degli errori

Quando esponi un sito pubblico, dovresti sempre disattivare DEBUG. Questo renderà il tuo server molto più veloce, e inoltre previene di mostrare a utenti malevoli i dettagli della tua applicazione che possono essere rivelati dalle pagine di errore.

Tuttavia, l’esecuzione con DEBUG impostato a False comporta che non saranno mai visibili gli errori generati dal tuo sito – al loro posto chiunque vedrà solo le pagine pubbliche di errore. Per tenere traccia degli errori che si verificano in un sito pubblicato, Django può essere configurato per creare reports con dettagli su tali errori.

Rapporti email

Errori del server

Quando DEBUG è False, Django invierà una mail agli utenti citati nel setting ADMINS ogni volta che il tuo codice lancerà un’eccezione non gestita e che risulterà come un error interno del server ( in poche parole, per ogni risposta con un codice HTTP 500 or maggiore ). Questo comporta un’immediata notifica agli amministratori di qualsiasi errore. Le persone specificate nel setting ADMINS riceveranno un descrizione dell’errore, un traceback Python completo, e i dettagli della richiesta HTTP che ha generato gli errori.

Nota

Per inviare e-mail, Django richiede alcune impostazioni che gli dicono come connettersi al tuo server di posta. Come minimo dovrai specificare EMAIL_HOST e presumibilmente EMAIL_HOST_USER e EMAIL_HOST_PASSWORD, anche se altre impostazioni potrebbero essere richieste a seconda della configurazione del tuo mail server. Consulta </ref/settings> per una lista completa delle impostazioni email

Di default, Django invierà le email da root@localhost. Ma, qualche mail provider rifiuta tutte le mail da questo indirizzo. Per utilizzare un indirizzo diverso, modifica il setting SERVER_EMAIL

Per attivare questo comportamento, inserisci l’indirizzo email del destinatario nella configurazione ADMINS .

Vedi anche

Le email di errori relativi al server sono inviate usando il framework di logging, puoi personalizzare questo comportamento in personalizza la configurazione del sistema di logging.

Errori 404

Django può essere configurato per inviare via email errori relativi ai link non funzionanti (errore 404 «pagina non trovata»). Django invia email relative ad errori 404 quando:

Se queste condizioni sono soddisfatte, Django invierà un’e-mail agli utenti elencati nell’impostazione MANAGERS ogni volta che il tuo codice genera un 404 e la richiesta ha un referer. Non si preoccupa di inviare e-mail per i 404 che non hanno un referer: di solito si tratta di persone che digitano URL non funzionanti o bot Web non funzionanti. Ignora anche i 404 quando il referer è uguale all’URL richiesto, poiché questo comportamento è dovuto anche a bot web rotti.

Nota

BrokenLinkEmailsMiddleware deve essere inserita prima di ogni altro middleware che intereccetti gli errori 404, come LocaleMiddleware o FlatpageFallbackMiddleware. Inseriscilo verso l’inizio del tuo setting MIDDLEWARE.

Puoi dire a Django di smettere di segnalare particolari 404 modificando l’impostazione IGNORABLE_404_URLS. Dovrebbe essere un elenco di oggetti di espressioni regolari compilati. Per esempio:

import re

IGNORABLE_404_URLS = [
    re.compile(r"\.(php|cgi)$"),
    re.compile(r"^/phpmyadmin/"),
]

In questo esempio, un 404 a qualsiasi URL che finisce con .php oppure .cgi non verrà riportato.Inoltre nessuna URL inizierà con /phpmyadmin/`.

Gli esempi seguenti mostrano come escludere alcune URLs standard che i browser ed i crawler richiedono con frequenza:

import re

IGNORABLE_404_URLS = [
    re.compile(r"^/apple-touch-icon.*\.png$"),
    re.compile(r"^/favicon\.ico$"),
    re.compile(r"^/robots\.txt$"),
]

(Nota bene che queste sono espressioni regolari, quindi mettiamo un backslash prima del punto per assicurarci l’interpretazione come carattere)

Se desideri personalizzare ulteriormente il comportamento di django.middleware.common.BrokenLinkEmailsMiddleware (ad esempio per ignorare le richieste provenienti dai web crawler), dovresti ereditare la classe e sovrascrivere i suoi metodi.

Vedi anche

Gli errori 404 vengono registrati utilizzando il logging framework. Di default, queste registrazioni sul log vengono ignorate, ma puoi usarle per la segnalazione di errori scrivendo un handler :doc:`configuring logging </topics/logging> “ in modo appropriato.

Filtra i report di errore

Avvertimento

Il filtraggio dei dati sensibili è un problema difficile ed è quasi impossibile garantire che i dati sensibili non vengano trasmessi in un report di errore. Pertanto, i report di errore dovrebbero essere disponibili solo per i membri del team affidabili e dovresti evitare di trasmettere report di errore non crittati su Internet (ad esempio tramite e-mail).

Filtraggio informazioni sensibili

I report sugli errori sono davvero utili per il loro debug, quindi è generalmente utile registrare quante più informazioni possibili a riguardo. Ad esempio, per impostazione predefinita Django registra il full traceback per l’eccezione sollevata, le variabili locali di ogni traceback frame e i attributes di HttpRequest.

Comunque, a volte alcuni tipi di informazioni possono essere troppo sensibili e quindi non può essere appropriato tenere traccia ad esempio, della password o del numero di carta di credito di un utente. Quindi oltre a filtrare le impostazioni che sono sensibili come descritto nella documentazione DEBUG, Django offre una serie di decoratori di funzioni che ti aiutano a controllare quali informazioni debbano essere filtrate sul report degli errori in ambiente di produzione (cioè con DEBUG impostato a False): sensitive_variables() e sensitive_post_parameters().

sensitive_variables(*variables)

Se una funzione (sia essa una view o una callback regolare) nel tuo codice usa variabili locali suscettibili di contenere infomazioni sensibili, puoi evitare che i valori di quelle variabili vengano inclusi nei report degli errori usando il decoratore sensitive_variables:

from django.views.decorators.debug import sensitive_variables


@sensitive_variables("user", "pw", "cc")
def process_info(user):
    pw = user.pass_word
    cc = user.credit_card_number
    name = user.name
    ...

Nell’esempio sopra, i valori delle variabili user, pw e cc verranno nascosti e sostituiti con asterischi (**********) nei report di errore, mentre verrà mostrato il valore della variabile name.

Per nascondere sistematicamente tutte e variabili locali di una funzione dal sistema di gestione degli errori nei log, non indicare alcun argomento al decoratore sensitive_variables:

@sensitive_variables()
def my_function():
    ...

Quando si utilizzano decoratori multipli

Se la variabile che vuoi nascondere è anche un argomento di funzione (ad es. “”user” nell’esempio seguente), e se la funzione decorata ha più decoratori, assicurati di posizionare @sensitive_variables in cima alla serie di decoratori. In questo modo nasconderà anche l’argomento della funzione mentre viene passato attraverso gli altri decoratori:

@sensitive_variables("user", "pw", "cc")
@some_decorator
@another_decorator
def process_info(user):
    ...

Avvertimento

Due to the machinery needed to cross the sync/async boundary, sync_to_async() and async_to_sync() are not compatible with sensitive_variables().

If using these adapters with sensitive variables, ensure to audit exception reporting, and consider implementing a custom filter if necessary.

sensitive_post_parameters(*parameters)

Se una delle tue view riceve un oggetto HttpRequest con POST parameters suscettibile di contenere informazioni riservate, puoi impedire che i valori di tali parametri siano inclusi nei report di error utilizzando il decoratore sensitive_post_parameters:

from django.views.decorators.debug import sensitive_post_parameters


@sensitive_post_parameters("pass_word", "credit_card_number")
def record_user_profile(request):
    UserProfile.create(
        user=request.user,
        password=request.POST["pass_word"],
        credit_card=request.POST["credit_card_number"],
        name=request.POST["name"],
    )
    ...

Nell’esempio di cui sopra, i valori dei parametri di POST per pass_word e credit_card_number saranno nascosti e rimpiazzati con degli asterischi (**********) nella rappresentazione della request nel report degli errori, dove invece il valore del parametro name sarà mostrato.

Per nascondere sistematicamente tutti i parametri di una richiesta POST nel report degli errori, non inserire alcun parametro al decoratore sensitive_post_parameters

@sensitive_post_parameters()
def my_view(request):
    ...

Tutti i parametri in POST sono sistematicamente filtrati dai report degli errori per alcune view django.contrib.auth.views (login, password_reset_confirm, password_change, add_view e user_change_password nell’amministrazione auth) per prevenire la fuoriuscita di informazioni sensibili come ad esempio le password utente.

Rapporti di errore personalizzati

Tutto ciò che fanno sensitive_variables() e sensitive_post_parameters() è, rispettivamente, annotare la funzione decorata con i nomi delle variabili sensibili e annotare l’oggetto HttpRequest con i nomi dei parametri POST sensibili, in modo che le informazioni possona essere successivamente filtrate dai report quando si verifica un errore. Il vero filtro viene eseguito dal filtro di report degli errori predefinito di Django: django.views.debug.SafeExceptionReporterFilter. Questo filtro utilizza le annotazioni dei decoratori per sostituire i valori corrispondenti con gli sterischi (**********) quando vengono prodotti i report di errore. Se desideri sovrascrivere o personalizzare questo comportamento predefinito per l’intero sito, devi definire la tua classe di filtro e dire a Django di usarla tramite l’impostazione DEFAULT_EXCEPTION_REPORTER_FILTER:

DEFAULT_EXCEPTION_REPORTER_FILTER = "path.to.your.CustomExceptionReporterFilter"

Puoi controllare in modo più granulare quale filtro utilizzare all’interno di una vista configurando il parametro exception_reporter_filter della HttpRequest:

def my_view(request):
    if request.user.is_authenticated:
        request.exception_reporter_filter = CustomExceptionReporterFilter()
    ...

La tua classe del filtro personalizzato ha bisogno di ereditare da django.views.debug.SafeExceptionReporterFilter e può sovrascrivere i seguenti attributi e metodi:

class SafeExceptionReporterFilter
cleansed_substitute

Il carattere da utilizzare per rimpiazzare valori sensibili. Di default viene rimpiazzato il valore di stringhe sensibili con l’asterisco (**********).

hidden_settings

Un oggetto di espressione regolare compilato per trovare le impostazioni ed i valori request.META considerati sensibili. In modo predefinito è equivalente a:

import re

re.compile(r"API|TOKEN|KEY|SECRET|PASS|SIGNATURE|HTTP_COOKIE", flags=re.IGNORECASE)
Changed in Django 4.2:

HTTP_COOKIE was added.

is_active(request)

Restituisce True per attivare il filtro in get_post_parameters() e get_traceback_frame_variables(). Di default, il filtro è attivo se DEBUG is False. Nota che i valori sensibili request.META sono sempre filtrati così come i valori di impostazioni sensibili, come descritto nella documentazione di DEBUG.

get_post_parameters(request)

Restituisce un dizionario filtrato di parametri POST. I valori sensibili sono rimpiazzati con cleansed_substitute.

get_traceback_frame_variables(request, tb_frame)

Restituisce un dizionario filtrato di variabili locali per una data finestra di traceback. I valori sensibili sono rimpiazzati con cleansed_substitute.

Se necessiti di personalizzare i report degli errori oltre ai filtri, potresti specificare una classe personalizzata per il report degli errori definendo l’impostazione DEFAULT_EXCEPTION_REPORTER:

DEFAULT_EXCEPTION_REPORTER = "path.to.your.CustomExceptionReporter"

Il reporter delle eccezioni è resposabile di compilare i dati per il report delle eccezioni e di formattarli come HTML in modo appropriato. (Il reporter delle eccezioni usa DEFAULT_EXCEPTION_REPORTER_FILTER quando prepara i dati di report delle eccezioni).

La tua classe report personalizzata deve ereditare da django.views.debug.ExceptionReporter.

class ExceptionReporter
html_template_path

Proprietà che restituisce un pathlib.Path che rappresenta il percorso assoluto sul filesystem di un template per fare render della rappresentazione HTML dell’eccezione. E” predefinito il template che offre Django.

text_template_path

Proprietà che restituisce un pathlib.Path che rappresenta il percorso assoluto sul filesystem di un template per fare render della rappresentazione in plain-text dell’eccezione. E” predefinito il template che offre Django.

get_traceback_data()

Restituisce un dizionario che contiene le informazioni utili per l’analisi

Questa è il punto principale dell’estensione per personalizzare i report delle eccezioni, per esempio:

from django.views.debug import ExceptionReporter


class CustomExceptionReporter(ExceptionReporter):
    def get_traceback_data(self):
        data = super().get_traceback_data()
        # ... remove/add something here ...
        return data
get_traceback_html()

Restituisce la versione HTML del report dell’eccezione

Usato per la versione HTML del debug della pagina di errore 500 HTTP.

get_traceback_text()

Restituisce una versione testuale del resoconto dell’eccezione

Usato per la versione testuale del debug della pagina di errore 500 HTTP e report email.

Così come con la classe filtro, puoi controllare quale classe per il report di eccezioni usare dentro ad ogni view impostando l’attributo exception_reporter_class di HttpRequest:

def my_view(request):
    if request.user.is_authenticated:
        request.exception_reporter_class = CustomExceptionReporter()
    ...

Vedi anche

Puoi anche approntare un report degli errori personalizzato scrivendo una parte di middleware delle eccezioni. personalizzato. Se scrivi un report degli errori personalizzato, è una buona idea simulare la gestione degli errori built-in di Django e fare report/log degli errori solo se DEBUG è False.

Back to Top