Просмотр исходного кода

Include the current ETag in the 412 response

Jeremy Stretch 2 дней назад
Родитель
Сommit
ec0fe62df5
2 измененных файлов с 12 добавлено и 1 удалено
  1. 7 1
      netbox/netbox/api/viewsets/__init__.py
  2. 5 0
      netbox/utilities/exceptions.py

+ 7 - 1
netbox/netbox/api/viewsets/__init__.py

@@ -61,7 +61,13 @@ class ETagMixin:
         if provided := self._get_if_match(request):
             current_etag = self._get_etag(instance)
             if current_etag and current_etag not in provided:
-                raise PreconditionFailed()
+                raise PreconditionFailed(etag=current_etag)
+
+    def handle_exception(self, exc):
+        response = super().handle_exception(exc)
+        if isinstance(exc, PreconditionFailed) and exc.etag:
+            response['ETag'] = exc.etag
+        return response
 
     def retrieve(self, request, *args, **kwargs):
         instance = self.get_object()

+ 5 - 0
netbox/utilities/exceptions.py

@@ -44,11 +44,16 @@ class PermissionsViolation(Exception):
 class PreconditionFailed(APIException):
     """
     Raised when an If-Match precondition is not satisfied (HTTP 412).
+    Optionally carries the current ETag so it can be included in the response.
     """
     status_code = status.HTTP_412_PRECONDITION_FAILED
     default_detail = 'Precondition failed.'
     default_code = 'precondition_failed'
 
+    def __init__(self, detail=None, code=None, etag=None):
+        super().__init__(detail=detail, code=code)
+        self.etag = etag
+
 
 class RQWorkerNotRunningException(APIException):
     """