# Documentazione Django 6.0.7

# 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

By default, Django will send email from `root@localhost`. However, some mail providers reject all email from this address. To use a different sender address, modify the `SERVER_EMAIL` setting.

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:

- `DEBUG` è `False`;

- La tua impostazione `MIDDLEWARE` include `django.middleware.common.BrokenLinkEmailsMiddleware`.

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): ...

sensitive_post_parameters(*parameters)

  If one of your views receives an `HttpRequest` object with `POST` parameters susceptible to contain sensitive information, you may prevent the values of those parameters from being included in the error reports using the `sensitive_post_parameters` decorator:

      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|AUTH|TOKEN|KEY|SECRET|PASS|SIGNATURE|HTTP_COOKIE", flags=re.IGNORECASE)

  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`.