1
0
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:
Jeremy Stretch
2020-02-21 17:21:04 -05:00
parent 12602a95ea
commit 9128dc961c
4 changed files with 29 additions and 3 deletions

View File

@ -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

View File

@ -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:

View File

@ -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
# #

View File

@ -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