mirror of
https://github.com/netbox-community/netbox.git
synced 2024-05-10 07:54:54 +00:00
Closes #4173: Return graceful error message when webhook queuing fails
This commit is contained in:
@ -1,5 +1,9 @@
|
|||||||
# v2.7.8 (FUTURE)
|
# v2.7.8 (FUTURE)
|
||||||
|
|
||||||
|
## Enhancements
|
||||||
|
|
||||||
|
* [#4173](https://github.com/netbox-community/netbox/issues/4173) - Return graceful error message when webhook queuing fails
|
||||||
|
|
||||||
## Bug Fixes
|
## Bug Fixes
|
||||||
|
|
||||||
* [#4224](https://github.com/netbox-community/netbox/issues/4224) - Fix display of rear device image if front image is not defined
|
* [#4224](https://github.com/netbox-community/netbox/issues/4224) - Fix display of rear device image if front image is not defined
|
||||||
|
@ -5,11 +5,14 @@ from copy import deepcopy
|
|||||||
from datetime import timedelta
|
from datetime import timedelta
|
||||||
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
|
from django.contrib import messages
|
||||||
from django.db.models.signals import pre_delete, post_save
|
from django.db.models.signals import pre_delete, post_save
|
||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
from django_prometheus.models import model_deletes, model_inserts, model_updates
|
from django_prometheus.models import model_deletes, model_inserts, model_updates
|
||||||
|
from redis.exceptions import RedisError
|
||||||
|
|
||||||
from extras.utils import is_taggable
|
from extras.utils import is_taggable
|
||||||
|
from utilities.api import is_api_request
|
||||||
from utilities.querysets import DummyQuerySet
|
from utilities.querysets import DummyQuerySet
|
||||||
from .choices import ObjectChangeActionChoices
|
from .choices import ObjectChangeActionChoices
|
||||||
from .models import ObjectChange
|
from .models import ObjectChange
|
||||||
@ -99,6 +102,7 @@ class ObjectChangeMiddleware(object):
|
|||||||
return response
|
return response
|
||||||
|
|
||||||
# Create records for any cached objects that were changed.
|
# Create records for any cached objects that were changed.
|
||||||
|
redis_failed = False
|
||||||
for instance, action in _thread_locals.changed_objects:
|
for instance, action in _thread_locals.changed_objects:
|
||||||
|
|
||||||
# Refresh cached custom field values
|
# Refresh cached custom field values
|
||||||
@ -114,7 +118,16 @@ class ObjectChangeMiddleware(object):
|
|||||||
objectchange.save()
|
objectchange.save()
|
||||||
|
|
||||||
# Enqueue webhooks
|
# Enqueue webhooks
|
||||||
enqueue_webhooks(instance, request.user, request.id, action)
|
try:
|
||||||
|
enqueue_webhooks(instance, request.user, request.id, action)
|
||||||
|
except RedisError as e:
|
||||||
|
if not redis_failed and not is_api_request(request):
|
||||||
|
messages.error(
|
||||||
|
request,
|
||||||
|
"There was an error processing webhooks for this request. Check that the Redis service is "
|
||||||
|
"running and reachable. The full error details were: {}".format(e)
|
||||||
|
)
|
||||||
|
redis_failed = True
|
||||||
|
|
||||||
# Increment metric counters
|
# Increment metric counters
|
||||||
if action == ObjectChangeActionChoices.ACTION_CREATE:
|
if action == ObjectChangeActionChoices.ACTION_CREATE:
|
||||||
|
@ -6,6 +6,7 @@ from django.contrib.contenttypes.models import ContentType
|
|||||||
from django.core.exceptions import FieldError, MultipleObjectsReturned, ObjectDoesNotExist
|
from django.core.exceptions import FieldError, MultipleObjectsReturned, ObjectDoesNotExist
|
||||||
from django.db.models import ManyToManyField, ProtectedError
|
from django.db.models import ManyToManyField, ProtectedError
|
||||||
from django.http import Http404
|
from django.http import Http404
|
||||||
|
from django.urls import reverse
|
||||||
from rest_framework.exceptions import APIException
|
from rest_framework.exceptions import APIException
|
||||||
from rest_framework.permissions import BasePermission
|
from rest_framework.permissions import BasePermission
|
||||||
from rest_framework.relations import PrimaryKeyRelatedField, RelatedField
|
from rest_framework.relations import PrimaryKeyRelatedField, RelatedField
|
||||||
@ -41,6 +42,14 @@ def get_serializer_for_model(model, prefix=''):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def is_api_request(request):
|
||||||
|
"""
|
||||||
|
Return True of the request is being made via the REST API.
|
||||||
|
"""
|
||||||
|
api_path = reverse('api-root')
|
||||||
|
return request.path_info.startswith(api_path)
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Authentication
|
# Authentication
|
||||||
#
|
#
|
||||||
|
@ -5,6 +5,7 @@ from django.db import ProgrammingError
|
|||||||
from django.http import Http404, HttpResponseRedirect
|
from django.http import Http404, HttpResponseRedirect
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
|
|
||||||
|
from .api import is_api_request
|
||||||
from .views import server_error
|
from .views import server_error
|
||||||
|
|
||||||
|
|
||||||
@ -38,9 +39,8 @@ class APIVersionMiddleware(object):
|
|||||||
self.get_response = get_response
|
self.get_response = get_response
|
||||||
|
|
||||||
def __call__(self, request):
|
def __call__(self, request):
|
||||||
api_path = reverse('api-root')
|
|
||||||
response = self.get_response(request)
|
response = self.get_response(request)
|
||||||
if request.path_info.startswith(api_path):
|
if is_api_request(request):
|
||||||
response['API-Version'] = settings.REST_FRAMEWORK_VERSION
|
response['API-Version'] = settings.REST_FRAMEWORK_VERSION
|
||||||
return response
|
return response
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user