Exceptions: have correct code/status_code for every error.
This commit is contained in:
parent
04231ebfe5
commit
c0575cb64c
10
django_etebase/exceptions.py
Normal file
10
django_etebase/exceptions.py
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
from rest_framework import serializers, status
|
||||||
|
|
||||||
|
|
||||||
|
class EtebaseValidationError(serializers.ValidationError):
|
||||||
|
def __init__(self, code, detail, status_code=status.HTTP_400_BAD_REQUEST):
|
||||||
|
super().__init__({
|
||||||
|
'code': code,
|
||||||
|
'detail': detail,
|
||||||
|
})
|
||||||
|
self.status_code = status_code
|
@ -18,10 +18,12 @@ from django.core.files.base import ContentFile
|
|||||||
from django.core import exceptions as django_exceptions
|
from django.core import exceptions as django_exceptions
|
||||||
from django.contrib.auth import get_user_model
|
from django.contrib.auth import get_user_model
|
||||||
from django.db import transaction
|
from django.db import transaction
|
||||||
from rest_framework import serializers
|
from rest_framework import serializers, status
|
||||||
from . import models
|
from . import models
|
||||||
from .utils import get_user_queryset, create_user
|
from .utils import get_user_queryset, create_user
|
||||||
|
|
||||||
|
from .exceptions import EtebaseValidationError
|
||||||
|
|
||||||
User = get_user_model()
|
User = get_user_model()
|
||||||
|
|
||||||
|
|
||||||
@ -40,7 +42,7 @@ def process_revisions_for_item(item, revision_data):
|
|||||||
chunk_obj.save()
|
chunk_obj.save()
|
||||||
else:
|
else:
|
||||||
if chunk_obj is None:
|
if chunk_obj is None:
|
||||||
raise serializers.ValidationError('Tried to create a new chunk without content')
|
raise EtebaseValidationError('chunk_no_content', 'Tried to create a new chunk without content')
|
||||||
|
|
||||||
chunks_objs.append(chunk_obj)
|
chunks_objs.append(chunk_obj)
|
||||||
|
|
||||||
@ -115,7 +117,7 @@ class ChunksField(serializers.RelatedField):
|
|||||||
|
|
||||||
def to_internal_value(self, data):
|
def to_internal_value(self, data):
|
||||||
if data[0] is None or data[1] is None:
|
if data[0] is None or data[1] is None:
|
||||||
raise serializers.ValidationError('null is not allowed')
|
raise EtebaseValidationError('null is not allowed')
|
||||||
return (data[0], b64decode_or_bytes(data[1]))
|
return (data[0], b64decode_or_bytes(data[1]))
|
||||||
|
|
||||||
|
|
||||||
@ -161,7 +163,7 @@ class CollectionItemSerializer(serializers.ModelSerializer):
|
|||||||
cur_etag = instance.etag if not created else None
|
cur_etag = instance.etag if not created else None
|
||||||
|
|
||||||
if validate_etag and cur_etag != etag:
|
if validate_etag and cur_etag != etag:
|
||||||
raise serializers.ValidationError('Wrong etag. Expected {} got {}'.format(cur_etag, etag))
|
raise EtebaseValidationError('wrong_etag', 'Wrong etag. Expected {} got {}'.format(cur_etag, etag), status_code=status.HTTP_409_CONFLICT)
|
||||||
|
|
||||||
if not created:
|
if not created:
|
||||||
# We don't have to use select_for_update here because the unique constraint on current guards against
|
# We don't have to use select_for_update here because the unique constraint on current guards against
|
||||||
@ -190,7 +192,7 @@ class CollectionItemDepSerializer(serializers.ModelSerializer):
|
|||||||
item = self.__class__.Meta.model.objects.get(uid=data['uid'])
|
item = self.__class__.Meta.model.objects.get(uid=data['uid'])
|
||||||
etag = data['etag']
|
etag = data['etag']
|
||||||
if item.etag != etag:
|
if item.etag != etag:
|
||||||
raise serializers.ValidationError('Wrong etag. Expected {} got {}'.format(item.etag, etag))
|
raise EtebaseValidationError('wrong_etag', 'Wrong etag. Expected {} got {}'.format(item.etag, etag), status_code=status.HTTP_409_CONFLICT)
|
||||||
|
|
||||||
return data
|
return data
|
||||||
|
|
||||||
@ -232,7 +234,7 @@ class CollectionSerializer(serializers.ModelSerializer):
|
|||||||
|
|
||||||
with transaction.atomic():
|
with transaction.atomic():
|
||||||
if etag is not None:
|
if etag is not None:
|
||||||
raise serializers.ValidationError('etag is not None')
|
raise EtebaseValidationError('bad_etag', 'etag is not null')
|
||||||
|
|
||||||
instance.save()
|
instance.save()
|
||||||
main_item = models.CollectionItem.objects.create(**main_item_data, collection=instance)
|
main_item = models.CollectionItem.objects.create(**main_item_data, collection=instance)
|
||||||
@ -297,7 +299,7 @@ class CollectionInvitationSerializer(serializers.ModelSerializer):
|
|||||||
request = self.context['request']
|
request = self.context['request']
|
||||||
|
|
||||||
if request.user.username == value.lower():
|
if request.user.username == value.lower():
|
||||||
raise serializers.ValidationError('Inviting yourself is not allowed')
|
raise EtebaseValidationError('no_self_invite', 'Inviting yourself is not allowed')
|
||||||
return value
|
return value
|
||||||
|
|
||||||
def create(self, validated_data):
|
def create(self, validated_data):
|
||||||
@ -393,15 +395,15 @@ class AuthenticationSignupSerializer(serializers.Serializer):
|
|||||||
try:
|
try:
|
||||||
instance = create_user(**user_data, password=None, first_name=user_data['username'], view=view)
|
instance = create_user(**user_data, password=None, first_name=user_data['username'], view=view)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
raise serializers.ValidationError(e)
|
raise EtebaseValidationError('generic', str(e))
|
||||||
|
|
||||||
if hasattr(instance, 'userinfo'):
|
if hasattr(instance, 'userinfo'):
|
||||||
raise serializers.ValidationError('User already exists')
|
raise EtebaseValidationError('user_exists', 'User already exists', status_code=status.HTTP_409_CONFLICT)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
instance.clean_fields()
|
instance.clean_fields()
|
||||||
except django_exceptions.ValidationError as e:
|
except django_exceptions.ValidationError as e:
|
||||||
raise serializers.ValidationError(e)
|
raise EtebaseValidationError('generic', str(e))
|
||||||
# FIXME: send email verification
|
# FIXME: send email verification
|
||||||
|
|
||||||
models.UserInfo.objects.create(**validated_data, owner=instance)
|
models.UserInfo.objects.create(**validated_data, owner=instance)
|
||||||
|
@ -72,7 +72,7 @@ from .serializers import (
|
|||||||
UserSerializer,
|
UserSerializer,
|
||||||
)
|
)
|
||||||
from .utils import get_user_queryset
|
from .utils import get_user_queryset
|
||||||
|
from .exceptions import EtebaseValidationError
|
||||||
|
|
||||||
User = get_user_model()
|
User = get_user_model()
|
||||||
|
|
||||||
@ -111,7 +111,14 @@ class BaseViewSet(viewsets.ModelViewSet):
|
|||||||
stoken = self.get_stoken_obj_id(request)
|
stoken = self.get_stoken_obj_id(request)
|
||||||
|
|
||||||
if stoken is not None:
|
if stoken is not None:
|
||||||
return get_object_or_404(Stoken.objects.all(), uid=stoken)
|
try:
|
||||||
|
return Stoken.objects.get(uid=stoken)
|
||||||
|
except Stoken.DoesNotExist:
|
||||||
|
raise EtebaseValidationError({
|
||||||
|
'code': 'bad_stoken',
|
||||||
|
'detail': 'Invalid stoken.',
|
||||||
|
},
|
||||||
|
status_code=status.HTTP_400_BAD_REQUEST)
|
||||||
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
@ -363,7 +370,7 @@ class CollectionItemViewSet(BaseViewSet):
|
|||||||
|
|
||||||
if stoken is not None and stoken != collection_object.stoken:
|
if stoken is not None and stoken != collection_object.stoken:
|
||||||
content = {'code': 'stale_stoken', 'detail': 'Stoken is too old'}
|
content = {'code': 'stale_stoken', 'detail': 'Stoken is too old'}
|
||||||
return Response(content, status=status.HTTP_400_BAD_REQUEST)
|
return Response(content, status=status.HTTP_409_CONFLICT)
|
||||||
|
|
||||||
items = request.data.get('items')
|
items = request.data.get('items')
|
||||||
deps = request.data.get('deps', None)
|
deps = request.data.get('deps', None)
|
||||||
@ -387,7 +394,7 @@ class CollectionItemViewSet(BaseViewSet):
|
|||||||
"items": serializer.errors,
|
"items": serializer.errors,
|
||||||
"deps": deps_serializer.errors if deps is not None else [],
|
"deps": deps_serializer.errors if deps is not None else [],
|
||||||
},
|
},
|
||||||
status=status.HTTP_400_BAD_REQUEST)
|
status=status.HTTP_409_CONFLICT)
|
||||||
|
|
||||||
|
|
||||||
class CollectionItemChunkViewSet(viewsets.ViewSet):
|
class CollectionItemChunkViewSet(viewsets.ViewSet):
|
||||||
|
Loading…
Reference in New Issue
Block a user