Gestion du signalement des erreurs¶
Lorsque vous faites fonctionner un site public, vous devriez toujours désactiver le réglage DEBUG
. Cela va accĂ©lĂ©rer le serveur et Ă©vitera aussi que des utilisateurs mal intentionnĂ©s puissent voir des dĂ©tails de lâapplication pouvant ĂȘtre rĂ©vĂ©lĂ©s dans les pages dâerreur.
Cependant, lorsquâun site fonctionne avec DEBUG
réglé à False
, vous ne verrez jamais les dĂ©tails des erreurs gĂ©nĂ©rĂ©s par le site ; tout le monde voit les mĂȘmes pages dâerreur publiques. Il est nĂ©cessaire de garder la trace des erreurs qui se produisent sur des sites en production, il est donc possible de configurer Django pour quâil crĂ©e des rapports incluant les dĂ©tails de ces erreurs.
Rapports par messagerie¶
Erreurs de serveur¶
Lorsque DEBUG
vaut False
, Django envoie un courriel aux utilisateurs énumérés dans le réglage ADMINS
Ă chaque fois que le code gĂ©nĂšre une exception non interceptĂ©e produisant une erreur interne de serveur (strictement parlant, pour toute rĂ©ponse ayant un code dâĂ©tat HTTP de 500 ou plus). Les administrateurs sont ainsi notifiĂ©s immĂ©diatement Ă la suite de toute erreur. Les personnes dans ADMINS
obtiennent une description de lâerreur, une trace Python complĂšte ainsi que des dĂ©tails sur la requĂȘte HTTP qui a causĂ© lâerreur.
Note
Pour pouvoir envoyer des courriels, Django a besoin de connaßtre certains réglages indiquant comment se connecter à un serveur de messagerie. Au minimum, il faut indiquer EMAIL_HOST
, et potentiellement EMAIL_HOST_USER
et EMAIL_HOST_PASSWORD
; selon la configuration du serveur de messagerie, il peut toutefois ĂȘtre nĂ©cessaire de dĂ©finir dâautres rĂ©glages. Consultez la documentation sur les rĂ©glages Django pour une liste complĂšte des rĂ©glages liĂ©s Ă lâenvoi de messages Ă©lectroniques.
Par dĂ©faut, Django envoie ses messages avec lâadresse dâorigine root@localhost. Toutefois, certains fournisseurs de messagerie rejettent tous les messages provenant de cette adresse. Pour utiliser une adresse dâexpĂ©diteur diffĂ©rente, modifiez le rĂ©glage SERVER_EMAIL
.
Pour activer ce comportement, placez les adresses électroniques des destinataires dans le réglage ADMINS
.
Voir aussi
Les messages dâerreur de serveur sont envoyĂ©s par le moyen de lâinfrastructure de journalisation, il est donc possible de personnaliser ce comportement en personnalisant la configuration de la journalisation.
Erreurs 404¶
Django peut aussi ĂȘtre configurĂ© pour envoyer des courriels pour des erreurs de lien cassĂ© (erreurs 404 « page non trouvĂ©e »). Django envoie des courriels lors dâerreurs 404 si :
DEBUG
vautFalse
;- Votre réglage
MIDDLEWARE
contientdjango.middleware.common.BrokenLinkEmailsMiddleware
.
Si ces conditions sont remplies, Django envoie un courriel aux utilisateurs mentionnés dans le réglage MANAGERS
chaque fois que le code signale une erreur 404 et que la requĂȘte possĂšde une URL rĂ©fĂ©rente (« referer »). Il ne prend pas la peine dâenvoyer un courriel pour une erreur 404 sans URL rĂ©fĂ©rente, car il sâagit gĂ©nĂ©ralement de personnes ayant mal saisi une adresse ou de robots Web dĂ©fectueux. Il ignore aussi les erreurs 404 lorsque lâURL rĂ©fĂ©rente est la mĂȘme que lâURL demandĂ©e, car ce comportement est aussi typique des robots Web dĂ©fectueux.
Note
BrokenLinkEmailsMiddleware
doit apparaĂźtre avant tout autre intergiciel interceptant les erreurs 404, tel que LocaleMiddleware
ou FlatpageFallbackMiddleware
. Placez-le dans les premiÚres lignes du réglage MIDDLEWARE
.
Il est possible dâindiquer Ă Django de ne pas signaler certaines erreurs 404 en ajustant le rĂ©glage IGNORABLE_404_URLS
. Celui-ci est une liste dâexpressions rĂ©guliĂšres compilĂ©es. Par exemple :
import re
IGNORABLE_404_URLS = [
re.compile(r'\.(php|cgi)$'),
re.compile(r'^/phpmyadmin/'),
]
Dans cet exemple, une erreur 404 vers toute URL se terminant par .php
ou .cgi
ne sera pas signalée. Ni aucune URL commençant par /phpmyadmin/
.
Lâexemple suivant montre comment exclure certaines URL conventionnellement demandĂ©es par les navigateurs et les robots :
import re
IGNORABLE_404_URLS = [
re.compile(r'^/apple-touch-icon.*\.png$'),
re.compile(r'^/favicon\.ico$'),
re.compile(r'^/robots\.txt$'),
]
(Notez quâil sâagit dâexpressions rĂ©guliĂšres, dâoĂč la prĂ©sence de la barre oblique inverse devant les points pour les Ă©chapper.)
Si vous souhaitez personnaliser davantage le comportement de django.middleware.common.BrokenLinkEmailsMiddleware
(par exemple pour ignorer les requĂȘtes en provenance de robots Web), vous devez crĂ©er une sous-classe et surcharger ses mĂ©thodes.
Voir aussi
Les erreurs 404 sont journalisĂ©es en utilisant lâinfrastructure de journalisation. Par dĂ©faut, ces entrĂ©es de journal sont ignorĂ©es, mais vous pouvez les utiliser pour le signalement dâerreurs en Ă©crivant un gestionnaire et en configurant la journalisation en consĂ©quence.
Filtrage de rapports dâerreur¶
Avertissement
Le filtrage des donnĂ©es sensibles est un problĂšme ardu, et il est quasiment impossible de garantir quâaucune donnĂ©e sensible ne figurera dans un rapport dâerreur. Il faudrait donc limiter lâaccĂšs aux rapports dâerreurs aux membres de votre Ă©quipe dignes de confiance et Ă©viter de transmettre ces rapports de maniĂšre non chiffrĂ©e par Internet (comme par exemple par messagerie Ă©lectronique).
Filtrage des informations sensibles¶
Les rapports dâerreur sont vraiment utiles pour dĂ©boguer les erreurs, il est donc gĂ©nĂ©ralement utile de rĂ©colter le maximum dâinformations Ă leur sujet. Par dĂ©faut, Django rĂ©colte une trace complĂšte de lâexception levĂ©e, les variables locales de chaque contexte de trace et les attributs de lâobjet HttpRequest
.
Il peut cependant arriver que certains types dâinformation soient trop sensibles et quâil nâest pas adĂ©quat dâen conserver la trace, par exemple un mot de passe ou un numĂ©ro de carte de crĂ©dit. En plus dâexclure les rĂ©glages apparaissant comme sensibles selon ce qui est expliquĂ© dans la documentation de DEBUG
, Django offre donc un ensemble de fonctions dĂ©coratrices pour vous aider Ă contrĂŽler les informations qui ne devraient pas apparaĂźtre dans les rapports dâerreur dans un environnement de production (câest-Ă -dire quand DEBUG
est défini à False
) : sensitive_variables()
et sensitive_post_parameters()
.
-
sensitive_variables
(*variables)¶ Si une fonction (une vue ou toute autre fonction de rappel) de votre code utilise des variables locales susceptibles de contenir des informations sensibles, vous pouvez empĂȘcher les valeurs de ces variables dâapparaĂźtre dans les rapports dâerreur en utilisant le dĂ©corateur
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 ...
Dans lâexemple ci-dessus, les valeurs des variables
user
,pw
etcc
seront masquées et remplacées par des étoiles (**********
) dans les rapports dâerreur, tandis que la valeur de la variablename
sera visible.Pour masquer systĂ©matiquement toutes les variables locales dâune fonction dans les journaux dâerreurs, nâindiquez aucun paramĂštre au dĂ©corateur
sensitive_variables
:@sensitive_variables() def my_function(): ...
Utilisation de plusieurs décorateurs
Si la variable que vous voulez masquer est également un paramÚtre de fonction (par ex.
user
dans lâexemple suivant) et si la fonction dĂ©corĂ©e possĂšde plusieurs dĂ©corateurs, prenez soin de placer@sensitive_variables
au sommet de la chaßne des décorateurs. De cette façon, le paramÚtre de fonction sera aussi masqué tout en passant par les autres décorateurs :@sensitive_variables('user', 'pw', 'cc') @some_decorator @another_decorator def process_info(user): ...
-
sensitive_post_parameters
(*parameters)¶ Si lâune de vos vues reçoit un objet
HttpRequest
avec desparamĂštres POST
susceptibles de contenir des informations sensibles, vous pouvez empĂȘcher les valeurs de ces paramĂštres dâapparaĂźtre dans les rapports dâerreur en utilisant le dĂ©corateursensitive_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'], ) ...
Dans lâexemple ci-dessus, les valeurs des paramĂštres POST
pass_word
etcredit_card_number
seront masquées et remplacées par des étoiles (**********
) dans la reprĂ©sentation de la requĂȘte dans le rapport dâerreur, tandis que la valeur du paramĂštrename
sera visible.Pour masquer systĂ©matiquement tous les paramĂštres POST dâune requĂȘte dans les rapports dâerreur, nâindiquez aucun paramĂštre au dĂ©corateur
sensitive_post_parameters
:@sensitive_post_parameters() def my_view(request): ...
Tous les paramĂštres POST sont systĂ©matiquement masquĂ©s dans les rapports dâerreur pour certaines vues
django.contrib.auth.views
(login
,password_reset_confirm
,password_change
etadd_view
, ainsi queuser_change_password
dans lâadministration deauth
) pour empĂȘcher la divulgation dâinformations sensibles comme les mots de passe.
Rapports dâerreur personnalisĂ©s¶
Tout ce que font sensitive_variables()
et sensitive_post_parameters()
, câest respectivement annoter la fonction dĂ©corĂ©e avec les noms des varaibles sensibles et annoter lâobjet HttpRequest
avec les noms des paramĂštres POST sensibles, afin que ces informations sensibles puissent ĂȘtre plus tard filtrĂ©es des rapports lorsquâune erreur se produit. Le vrai filtrage est effectuĂ© par le filtre de rapport dâerreur par dĂ©faut de Django, django.views.debug.SafeExceptionReporterFilter
. Ce filtre utilise les annotations des décorateurs pour remplacer les valeurs correspondantes par des étoiles (**********
) au moment de la production du rapport dâerreur. Si vous souhaitez surcharger ou personnaliser ce comportement par dĂ©faut pour tout votre site, vous devez dĂ©finir votre propre classe de filtre et indiquer Ă Django de lâutiliser par le moyen du rĂ©glage DEFAULT_EXCEPTION_REPORTER_FILTER
:
DEFAULT_EXCEPTION_REPORTER_FILTER = 'path.to.your.CustomExceptionReporterFilter'
Vous pouvez aussi contrĂŽler dâune maniĂšre plus fine le filtre quâune vue donnĂ©es doit utiliser en dĂ©finissant lâattribut exception_reporter_filter
de lâobjet HttpRequest
.
def my_view(request):
if request.user.is_authenticated:
request.exception_reporter_filter = CustomExceptionReporterFilter()
...
Votre classe de filtre personnalisée doit hériter de django.views.debug.SafeExceptionReporterFilter
et peut surcharger les attributs et méthodes suivantes :
-
class
SafeExceptionReporterFilter
¶ -
cleansed_substitute
¶ La valeur textuelle qui remplacera les données sensibles. Par défaut, il remplace les valeurs des variables sensibles par des étoiles (
**********
).
Un objet dâexpression rĂ©guliĂšre compilĂ©e utilisĂ© pour dĂ©couvrir les valeurs de rĂ©glages et de
request.META
considĂ©rĂ©es comme sensibles. Ăquivaut par dĂ©faut Ăimport re re.compile(r'API|TOKEN|KEY|SECRET|PASS|SIGNATURE', flags=re.IGNORECASE)
-
is_active
(request)¶ Renvoie
True
pour activer le filtrage dansget_post_parameters()
etget_traceback_frame_variables()
. Par défaut, le filtre est actif siDEBUG
vautFalse
. Notez que les valeurs sensibles derequest.META
sont toujours filtrées en compagnie des valeurs sensibles de réglages, tel que décrit dans la documentation deDEBUG
.
-
get_post_parameters
(request)¶ Renvoie le dictionnaire filtré des paramÚtres POST. Les valeurs des données sensibles sont remplacées par
cleansed_substitute
.
-
get_traceback_frame_variables
(request, tb_frame)¶ Renvoie le dictionnaire filtrĂ© des variables locales pour la trace dâerreur donnĂ©e. Les valeurs des donnĂ©es sensibles sont remplacĂ©es par
cleansed_substitute
.
-
Si vous avez besoin de personnaliser les rapports dâerreur au-delĂ du filtrage en place, vous pouvez indiquer une classe personnalisĂ©e de rapport dâerreur en dĂ©finissant le rĂ©glage DEFAULT_EXCEPTION_REPORTER
:
DEFAULT_EXCEPTION_REPORTER = 'path.to.your.CustomExceptionReporter'
Le rapporteur dâexception est responsable de compiler les donnĂ©es du rapport dâexception et de le mettre en forme adĂ©quatement en texte ou HTML (le rapporteur dâexception utilise DEFAULT_EXCEPTION_REPORTER_FILTER
lors de la prĂ©paration des donnĂ©es du rapport dâexception).
Votre classe de rapporteur personnalisée doit hériter de django.views.debug.ExceptionReporter
.
-
class
ExceptionReporter
¶ -
html_template_path
¶ - New in Django 3.2.
Propriété qui renvoie un chemin
pathlib.Path
reprĂ©sentant le chemin de systĂšme de fichiers absolu vers un gabarit pour le rendu de la reprĂ©sentation HTML de lâexception. Par dĂ©faut, câest le gabarit fourni par Django qui est utilisĂ©.
-
text_template_path
¶ - New in Django 3.2.
Propriété qui renvoie un chemin
pathlib.Path
reprĂ©sentant le chemin de systĂšme de fichiers absolu vers un gabarit pour le rendu de la reprĂ©sentation en texte pur de lâexception. Par dĂ©faut, câest le gabarit fourni par Django qui est utilisĂ©.
-
get_traceback_data
()¶ Renvoie un dictionnaire contenant les informations de trace dâerreur.
Il sâagit du point dâextension principal pour la personnalisation des rapports dâexception, par exemple
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
()¶ Renvoie une version HTML du rapport dâexception.
UtilisĂ© pour la version HTML de la page dâerreur HTTP 500 de dĂ©bogage.
-
get_traceback_text
()¶ Renvoie une version en texte brut du rapport dâexception.
UtilisĂ© pour la version texte brut de la page dâerreur HTTP 500 de dĂ©bogage et pour les rapports envoyĂ©s par courriel.
-
Comme avec la classe de filtre, vous pouvez contrĂŽler quelle classe de rapporteur dâexception utiliser dans une vue donnĂ©e en dĂ©finissant lâattribut exception_reporter_class
de HttpRequest
:
def my_view(request):
if request.user.is_authenticated:
request.exception_reporter_class = CustomExceptionReporter()
...
Voir aussi
Il est aussi imaginable de personnaliser les rapports dâerreurs en Ă©crivant un middleware dâexception appropriĂ©. Dans ce cas, il est conseillĂ© dâimiter la gestion dâerreur intĂ©grĂ©e dans Django et de ne notifier les erreurs que dans le cas oĂč DEBUG
vaut False
.