1
votes

Comment gérer une exception dans un middleware Django?

J'ai un problème avec la gestion correcte d'une exception dans le middleware Django. Mon exception:

class PatchRequestUserWithProfile:
def __init__(self, get_response):
    self.get_response = get_response

def __call__(self, request, *args, **kwargs):
    patch_request_for_nonanon_user(request)
    if not request.user.profile:
        raise MyProfileAuthorizationError("You are not allowed to use this profile.")

    response = self.get_response(request)
    return response

Et mon middleware:

from rest_framework.exceptions import APIException
from rest_framework.status import HTTP_403_FORBIDDEN
class MyProfileAuthorizationError(APIException):    
    def __init__(self, msg):
        APIException.__init__(self, msg)
        self.status_code = HTTP_403_FORBIDDEN
        self.message = msg

Et cette exception génère 500 au lieu de 403. Comment puis-je résoudre ce problème?


3 commentaires

pouvez-vous ajouter le suivi d'erreur?


MyProfileAuthorizationError cela renvoie 500?


@gachdavit oui, ça l'est. Il semble qu'il ne soit pas traité comme une exception http, mais comme une erreur habituelle.


3 Réponses :


1
votes

Au lieu d'utiliser Middleware, je pense que vous devriez utiliser les autorisations :

'DEFAULT_PERMISSION_CLASSES': (
   'path.to.CustomAccessPermission',
)

Et ajoutez ceci dans DEFAULT_PERMISSION_CLASSES pour le rendre disponible pour chaque vue d'API.

from rest_framework import permissions

class CustomAccessPermission(permissions.BasePermission):
    message = 'You are not allowed to use this profile.'

    def has_permission(self, request, view):
       if not request.user.profile:
           return False
       return True

p>


5 commentaires

non, si j'appelle super ici - il ne renvoie rien, je l'ai testé - aucune réponse des retours d'application.


désolé, qu'entendez-vous par ça ne renvoie rien ?


cela signifie que je ne reçois aucune réponse de l'application dans ce cas - il gère


mais dans ce cas je dois attribuer cette autorisation à tous mes ensembles de vues dans l'ensemble de mon projet?


non, il sera ajouté à tous les ensembles de vues. Si vous souhaitez que certains ensembles de vues aient un comportement différent, vous devez remplacer leur attribut permission_classes .



1
votes

Essayez avec cette exception:

from rest_framework.exceptions import APIException

class MyProfileAuthorizationError(APIException):
    status_code = 403
    default_detail = 'You are not allowed to use this profile'
    default_code = 'forbidden'

Je pense que vous ne pouvez pas faire cela, lisez ceci: https://groups.google.com/forum/#!topic/django-developers/-ncPqVzF8W8


1 commentaires

Le même problème demeure: 500 au lieu de 403



6
votes

Essayez de renvoyer un Réponse HttpResponseForbidden au lieu de lever l'exception

from django.http import HttpResponseForbidden


class PatchRequestUserWithProfile:
    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request, *args, **kwargs):
        patch_request_for_nonanon_user(request)
        if not request.user.profile:
            return HttpResponseForbidden("You are not allowed to use this profile.")

        response = self.get_response(request)
        return response


1 commentaires

Boom! C'est tout! Merci beaucoup! J'ai également essayé de renvoyer une réponse, mais je n'étais pas au courant de l'existence de HttpResponseForbidden.