Django - gestion des exceptions, meilleure pratique et envoi d'un message d'erreur personnalisé
Je commence à réfléchir à des la gestion des exceptions dans mon Django app, et mon objectif est de le rendre aussi convivial que possible. Par la convivialité, je suppose que l'utilisateur doit toujours obtenir une clarification détaillée sur ce qui s'est mal passé.
La suite sur ce post, la meilleure pratique consiste à
l'utilisation d'une réponse JSON avec le statut de 200 pour vos réactions normales et
de retour d'un (!) 4xx/5xx réponse pour les erreurs. Celles-ci peuvent apporter
La charge utile JSON, trop, de sorte que votre côté serveur peut ajouter des détails supplémentaires
à propos de l'erreur.
J'ai essayé de google, les mots clés de cette réponse, par toujours plus de questions que de réponses dans ma tête.
- Comment puis-je décider sur quel code d'erreur - 400 ou 500 - retour? Je veux dire, Django a de nombreux prédéfinis types d'erreur, et comment puis-je mettre en œuvre cette correspondance entre Django types d'exceptions et de 400-500 code d'erreur de faire l'exception de la manipulation de blocs SEC et réutilisables que possible?
- Pouvez l'approche avec le middleware suggéré par @Reorx dans le post être considérée comme viable ? ( La réponse a obtenu seulement un upvote, donc me faire hésiter à se plonger dans les détails et de les mettre en œuvre dans mon projet
- Plus important encore, parfois, je pourrait soulever une erreur liée à la logique métier, plutôt que de syntaxe incorrecte ou quelque chose de standard comme valeur null. Par exemple, si il n'y a pas de PDG dans mon entité juridique, que je veuille interdire à l'utilisateur de l'ajout d'un contrat. Quel devrait être le statut de l'erreur dans ce cas, et comment dois-je jeter une erreur avec mon explication détaillée de l'erreur pour l'utilisateur?
Penchons-nous sur un simple point de vue
def test_view (request):
try:
# Some code ....
if my_business_logic_is_violated():
# How do I raise the error
error_msg = "You violated bussiness logic because..."
# How do I pass error_msg
my_response = {'my_field' : value}
except ExpectedError as e:
# what is the most appropriate way to pass both error status and custom message
# How do I list all possible error types here (instead of ExpectedError to make the exception handling block as DRY and reusable as possible
return JsonResponse({'status':'false','message':message}, status=500)
source d'informationauteur Edgar Navasardyan
Vous devez vous connecter pour publier un commentaire.
Tout d'abord, vous devriez penser à ce que les erreurs que vous souhaitez exposer:
Généralement 4xx (erreurs qui sont attribués pour le côté client) sont présentés de sorte que l'utilisateur peut corriger la demande.
De l'autre côté, 5xx (erreurs qui sont attribués à côté serveur) sont généralement présentés sans information. À mon avis, pour ceux que vous devriez utiliser des outils comme Sentry faire surveiller et résoudre ces erreurs, qui peuvent avoir des problèmes de sécurité intégré.
Ayant cela à l'esprit, à mon avis, pour une bonne requête Ajax, il faut retourner un code d'état, et puis certains json pour aider à comprendre ce qui s'est passé comme un message et une explication (le cas échéant).
Si votre objectif est d'utiliser ajax pour soumettre des informations je vous suggérons de définir un formulaire pour ce que vous voulez. De cette façon, vous avez passé de certains des processus de validation avec la facilité. J'assumerai le cas, est-ce dans l'exemple.
Première - la demande Est-elle correcte?
Deuxième - y a t il des erreurs dans le formulaire?
Vous pouvez même obtenir de l'erreur de champ par champ, de sorte que vous pouvez présentée dans une meilleure façon dans le formulaire lui-même.
Troisième - traitons à la demande
En fonction de l'exception de définir des codes différents peuvent être nécessaires. Aller à Wikipedia et vérifiez la liste.
N'oubliez pas que la réponse varie également dans le code. Si vous ajouter quelque chose à la base de données vous devez retourner un
201
. Si vous venez de recevoir de l'information, puis vous avez été à la recherche pour une requête GET.De répondre aux questions
Django exceptions sera de retour de 500 erreurs si pas traitée, parce que si vous ne savez pas qu'une exception va arriver, alors c'est une erreur dans le serveur. À l'exception de 404 et identifiants de connexion je ne
try catch
blocs pour tout. (404 vous pouvez le soulever et si vous ne@login_required
ou une autorisation requis django répondra avec le code approprié sans que vous fassiez quoi que ce soit).Je ne suis pas complètement d'accord à la démarche. Comme vous l'avez dit les erreurs doivent être explicite ce que vous devez savoir toujours ce qui est supposé se produire et comment l'expliquer, et de le rendre fiable sur l'opération effectuée.
Je dirais une erreur 400 est ok pour que. C'est une mauvaise demande, vous avez juste besoin d'expliquer pourquoi, le code d'erreur est pour vous et pour votre code js afin d'être cohérente.
(exemple fourni) - Dans le
text_view
vous devriez avoir letest_method
comme dans le troisième exemple.La méthode d'essai doit avoir la structure suivante:
Le dans mon exemple:
J'ai considéré la logique d'affaires de violation d'être un Client d'Erreur parce que si quelque chose est nécessaire avant que demande le client doit être conscient de cela et demander à l'utilisateur de le faire en premier. (À partir de la Erreur De Définition):
Par la manière, consultez le Python Docs sur défini par l'Utilisateur Exceptions de sorte que vous pouvez donner les messages d'erreur appropriés. L'idée derrière cet exemple est que vous soulevez un
BusinessLogicViolation
exception avec un message différent demy_business_logic_is_violated()
en fonction de l'endroit où il a été généré.Les codes d'état sont très bien définis dans le protocole HTTP. Vous pouvez trouver un très lisible liste sur Wikipedia. Fondamentalement, les erreurs dans les 4XX gamme sont les erreurs commises par le client, c'est à dire si ils demande une ressource qui n'existe pas, etc. Les erreurs dans la 5XX plage doit être retourné si une erreur est rencontrée côté serveur.
En ce qui concerne le point numéro 3, vous devez choisir une erreur 4XX pour le cas où une condition préalable n'a pas été respectée, par exemple
428 Precondition Required
mais le retour d'un 5XX erreur lorsqu'un serveur génère une erreur de syntaxe.L'un des problèmes avec votre exemple est qu'aucune réponse n'est renvoyée, à moins que le serveur génère une exception spécifique, c'est à dire lorsque le code s'exécute normalement et aucune exception n'est levée, ni le message ni le code d'état est explicitement adressé au client. Cela peut être pris en charge par l'intermédiaire d'un bloc finally, pour cette partie de code aussi générique que possible.
Que par votre exemple:
Toutefois, comme indiqué dans les commentaires, il serait plus logique de faire les deux validations de la même manière, c'est à dire via des exceptions, comme suit: