Closes #5304: Return server error messages as JSON when handling REST API requests

This commit is contained in:
Jeremy Stretch 2020-11-04 17:11:57 -05:00
parent c53990c739
commit f845eeb117
3 changed files with 28 additions and 5 deletions

View File

@ -2,6 +2,10 @@
## v2.9.9 (FUTURE) ## v2.9.9 (FUTURE)
### Enhancements
* [#5304](https://github.com/netbox-community/netbox/issues/5304) - Return server error messages as JSON when handling REST API requests
### Bug Fixes ### Bug Fixes
* [#5271](https://github.com/netbox-community/netbox/issues/5271) - Fix auto-population of region field when editing a device * [#5271](https://github.com/netbox-community/netbox/issues/5271) - Fix auto-population of region field when editing a device

View File

@ -7,7 +7,7 @@ from django.http import Http404, HttpResponseRedirect
from django.urls import reverse from django.urls import reverse
from .api import is_api_request from .api import is_api_request
from .views import server_error from .views import server_error, rest_api_server_error
class LoginRequiredMiddleware(object): class LoginRequiredMiddleware(object):
@ -86,6 +86,10 @@ class ExceptionHandlingMiddleware(object):
if isinstance(exception, Http404): if isinstance(exception, Http404):
return return
# Handle exceptions that occur from REST API requests
if is_api_request(request):
return rest_api_server_error(request)
# Determine the type of exception. If it's a common issue, return a custom error page with instructions. # Determine the type of exception. If it's a common issue, return a custom error page with instructions.
custom_template = None custom_template = None
if isinstance(exception, ProgrammingError): if isinstance(exception, ProgrammingError):

View File

@ -13,7 +13,7 @@ from django.core.exceptions import FieldDoesNotExist, ImproperlyConfigured, Obje
from django.db import transaction, IntegrityError from django.db import transaction, IntegrityError
from django.db.models import ManyToManyField, ProtectedError from django.db.models import ManyToManyField, ProtectedError
from django.forms import Form, ModelMultipleChoiceField, MultipleHiddenInput, Textarea from django.forms import Form, ModelMultipleChoiceField, MultipleHiddenInput, Textarea
from django.http import HttpResponse, HttpResponseServerError from django.http import HttpResponse, HttpResponseServerError, JsonResponse
from django.shortcuts import get_object_or_404, redirect, render from django.shortcuts import get_object_or_404, redirect, render
from django.template import loader from django.template import loader
from django.template.exceptions import TemplateDoesNotExist from django.template.exceptions import TemplateDoesNotExist
@ -27,6 +27,7 @@ from django.views.decorators.csrf import requires_csrf_token
from django.views.defaults import ERROR_500_TEMPLATE_NAME from django.views.defaults import ERROR_500_TEMPLATE_NAME
from django.views.generic import View from django.views.generic import View
from django_tables2 import RequestConfig from django_tables2 import RequestConfig
from rest_framework import status
from extras.models import CustomField, CustomFieldValue, ExportTemplate from extras.models import CustomField, CustomFieldValue, ExportTemplate
from extras.querysets import CustomFieldQueryset from extras.querysets import CustomFieldQueryset
@ -1423,8 +1424,22 @@ def server_error(request, template_name=ERROR_500_TEMPLATE_NAME):
type_, error, traceback = sys.exc_info() type_, error, traceback = sys.exc_info()
return HttpResponseServerError(template.render({ return HttpResponseServerError(template.render({
'python_version': platform.python_version(),
'netbox_version': settings.VERSION,
'exception': str(type_),
'error': error, 'error': error,
'exception': str(type_),
'netbox_version': settings.VERSION,
'python_version': platform.python_version(),
})) }))
def rest_api_server_error(request, *args, **kwargs):
"""
Handle exceptions and return a useful error message for REST API requests.
"""
type_, error, traceback = sys.exc_info()
data = {
'error': str(error),
'exception': type_.__name__,
'netbox_version': settings.VERSION,
'python_version': platform.python_version(),
}
return JsonResponse(data, status=status.HTTP_500_INTERNAL_SERVER_ERROR)