Skip to content
Snippets Groups Projects
Commit 61213a55 authored by Samuel GAIST's avatar Samuel GAIST
Browse files

[common][api] Generate DRF exception rather that returning configured responses on error

This will make the code cleaner and allow to do custom
error handling properly.
parent fc90a242
No related branches found
No related tags found
1 merge request!327Refactor update creation api
...@@ -30,10 +30,10 @@ from django.shortcuts import get_object_or_404 ...@@ -30,10 +30,10 @@ from django.shortcuts import get_object_or_404
from rest_framework import status from rest_framework import status
from rest_framework import generics from rest_framework import generics
from rest_framework import permissions from rest_framework import permissions
from rest_framework import exceptions as drf_exceptions
from rest_framework.response import Response from rest_framework.response import Response
from rest_framework.reverse import reverse from rest_framework.reverse import reverse
from .responses import BadRequestResponse, ForbiddenResponse
from .models import Contribution, Versionable from .models import Contribution, Versionable
from .permissions import IsAuthor from .permissions import IsAuthor
from .exceptions import ShareError, BaseCreationError from .exceptions import ShareError, BaseCreationError
...@@ -86,9 +86,7 @@ class ShareView(CommonContextMixin, generics.CreateAPIView): ...@@ -86,9 +86,7 @@ class ShareView(CommonContextMixin, generics.CreateAPIView):
def post(self, request, *args, **kwargs): def post(self, request, *args, **kwargs):
serializer = self.get_serializer(data=request.data) serializer = self.get_serializer(data=request.data)
if not serializer.is_valid(): serializer.is_valid(raise_exception=True)
return BadRequestResponse(serializer.errors)
data = serializer.data data = serializer.data
object_db = self.get_queryset() object_db = self.get_queryset()
...@@ -96,7 +94,9 @@ class ShareView(CommonContextMixin, generics.CreateAPIView): ...@@ -96,7 +94,9 @@ class ShareView(CommonContextMixin, generics.CreateAPIView):
try: try:
self.do_share(object_db, data) self.do_share(object_db, data)
except ShareError as e: except ShareError as e:
return BadRequestResponse(e.errors) # ShareError happens when someone does not have access to
# all dependencies that should be shared.
raise drf_exceptions.PermissionDenied(e.errors)
return Response(object_db.sharing_preferences()) return Response(object_db.sharing_preferences())
...@@ -160,16 +160,14 @@ class ListCreateBaseView( ...@@ -160,16 +160,14 @@ class ListCreateBaseView(
def post(self, request, *args, **kwargs): def post(self, request, *args, **kwargs):
serializer = self.get_serializer(data=request.data) serializer = self.get_serializer(data=request.data)
if serializer.is_valid(): serializer.is_valid(raise_exception=True)
try: try:
if hasattr(self.model, "author"): if hasattr(self.model, "author"):
db_object = serializer.save(author=request.user) db_object = serializer.save(author=request.user)
else: else:
db_object = serializer.save() db_object = serializer.save()
except BaseCreationError as e: except BaseCreationError as e:
return BadRequestResponse(e.errors) raise drf_exceptions.APIException(e.errors)
else:
return BadRequestResponse(serializer.errors)
result = { result = {
"name": db_object.name, "name": db_object.name,
...@@ -201,32 +199,28 @@ class DiffView(generics.RetrieveAPIView): ...@@ -201,32 +199,28 @@ class DiffView(generics.RetrieveAPIView):
def get(self, request, author1, name1, version1, author2, name2, version2): def get(self, request, author1, name1, version1, author2, name2, version2):
# Retrieve the objects # Retrieve the objects
try: object1 = get_object_or_404(
object1 = self.model.objects.get( self.model,
author__username__iexact=author1, author__username__iexact=author1,
name__iexact=name1, name__iexact=name1,
version=int(version1), version=int(version1),
) )
except Exception:
return Response("%s/%s/%s" % (author1, name1, version1), status=404)
try: object2 = get_object_or_404(
object2 = self.model.objects.get( self.model,
author__username__iexact=author2, author__username__iexact=author2,
name__iexact=name2, name__iexact=name2,
version=int(version2), version=int(version2),
) )
except Exception:
return Response("%s/%s/%s" % (author2, name2, version2), status=404)
# Check that the user can access them # Check that the user can access them
accessibility = object1.accessibility_for(request.user) accessibility = object1.accessibility_for(request.user)
if not accessibility[0]: if not accessibility[0]:
return ForbiddenResponse(object1.fullname()) raise drf_exceptions.PermissionDenied(object1.fullname())
accessibility = object2.accessibility_for(request.user) accessibility = object2.accessibility_for(request.user)
if not accessibility[0]: if not accessibility[0]:
return ForbiddenResponse(object2.fullname()) raise drf_exceptions.PermissionDenied(object2.fullname())
# Compute the diff # Compute the diff
serializer = self.get_serializer({"object1": object1, "object2": object2}) serializer = self.get_serializer({"object1": object1, "object2": object2})
...@@ -269,13 +263,13 @@ class RetrieveUpdateDestroyContributionView( ...@@ -269,13 +263,13 @@ class RetrieveUpdateDestroyContributionView(
db_objects = self.get_queryset() db_objects = self.get_queryset()
if db_objects.count() == 0: if db_objects.count() == 0:
return Response(status=404) raise drf_exceptions.NotFound()
db_object = db_objects[0] db_object = db_objects[0]
version = int(self.kwargs.get("version", -1)) version = int(self.kwargs.get("version", -1))
if version != -1 and db_object.version != version: if version != -1 and db_object.version != version:
return Response(status=404) raise drf_exceptions.NotFound()
# Process the query string # Process the query string
allow_sharing = hasattr(db_object, "author") and ( allow_sharing = hasattr(db_object, "author") and (
...@@ -296,7 +290,9 @@ class RetrieveUpdateDestroyContributionView( ...@@ -296,7 +290,9 @@ class RetrieveUpdateDestroyContributionView(
# Retrieve the object # Retrieve the object
if version is None: if version is None:
return BadRequestResponse("A version number must be provided") raise drf_exceptions.ValidationError(
{"version": "A version number must be provided"}
)
db_object = get_object_or_404( db_object = get_object_or_404(
self.model, self.model,
...@@ -307,7 +303,7 @@ class RetrieveUpdateDestroyContributionView( ...@@ -307,7 +303,7 @@ class RetrieveUpdateDestroyContributionView(
# Check that the object can be deleted # Check that the object can be deleted
if not (db_object.deletable()): if not (db_object.deletable()):
return ForbiddenResponse( raise drf_exceptions.MethodNotAllowed(
"The {} can't be deleted anymore (needed by an attestation, an algorithm or another data format)".format( "The {} can't be deleted anymore (needed by an attestation, an algorithm or another data format)".format(
db_object.model_name() db_object.model_name()
) )
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment