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)
## Enhancements
* [#4173](https://github.com/netbox-community/netbox/issues/4173) - Return graceful error message when webhook queuing fails
## Bug Fixes
* [#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 django.conf import settings
from django.contrib import messages
from django.db.models.signals import pre_delete, post_save
from django.utils import timezone
from django_prometheus.models import model_deletes, model_inserts, model_updates
from redis.exceptions import RedisError
from extras.utils import is_taggable
from utilities.api import is_api_request
from utilities.querysets import DummyQuerySet
from .choices import ObjectChangeActionChoices
from .models import ObjectChange
@ -99,6 +102,7 @@ class ObjectChangeMiddleware(object):
return response
# Create records for any cached objects that were changed.
redis_failed = False
for instance, action in _thread_locals.changed_objects:
# Refresh cached custom field values
@ -114,7 +118,16 @@ class ObjectChangeMiddleware(object):
objectchange.save()
# 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
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.db.models import ManyToManyField, ProtectedError
from django.http import Http404
from django.urls import reverse
from rest_framework.exceptions import APIException
from rest_framework.permissions import BasePermission
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
#

View File

@ -5,6 +5,7 @@ from django.db import ProgrammingError
from django.http import Http404, HttpResponseRedirect
from django.urls import reverse
from .api import is_api_request
from .views import server_error
@ -38,9 +39,8 @@ class APIVersionMiddleware(object):
self.get_response = get_response
def __call__(self, request):
api_path = reverse('api-root')
response = self.get_response(request)
if request.path_info.startswith(api_path):
if is_api_request(request):
response['API-Version'] = settings.REST_FRAMEWORK_VERSION
return response