4

When using a malformed UUID in django-rest-framework the server throws an exception and returns status-code 500. The exception ValueError 'badly formed hexadecimal UUID string' isn't handled.

It makes more sense to handle it properly and return a status code 400.

I managed to do that with a custom exception handler but it's a really messy and ugly solution.

I thought about doing it with a custom serializer, but I wasn't sure how to handle this properly and if this is the right django approach.

What do you think?

Cheers.

Yaniv Peer
  • 161
  • 6

2 Answers2

1

I solved this by overriding the ViewSet since it is responsible for getting the object before passing it to the serializer. For convience I created UUIDViewSetMixin to add it to the desired view sets.

class UUIDViewSetMixin(object):
    lookup_field = 'id'

    def get_object(self):
        value = self.kwargs.get(self.lookup_field)
        try:
            uuid.UUID(value)
        except ValueError:
            result = {
                'code': 'bad_request',
                'message': _("'%(value)s' is not a valid uuid") % {'value', value}
            }
            return JsonResponse(data=data, request=status=status.HTTP_400_BAD_REQUEST)
        return super(UUIDViewSetMixin, self).get_object()
Nour Wolf
  • 2,140
  • 25
  • 24
1

Adding

lookup_value_regex = '[0-9a-fA-F]{8}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{12}' 

to a view uses django validation to only allow UUIDs to get processed and otherwise it just automatically gets a 404.

https://www.django-rest-framework.org/api-guide/routers/

Example in docs:

class MyModelViewSet(mixins.RetrieveModelMixin, viewsets.GenericViewSet):
    lookup_field = 'my_model_id'
    lookup_value_regex = '[0-9a-f]{32}'
Coder
  • 2,153
  • 1
  • 16
  • 21
Felix
  • 71
  • 7