mirror of
https://github.com/netbox-community/netbox.git
synced 2024-05-10 07:54:54 +00:00
Closes #1683: Replaced default 500 handler with custom middleware to provide preliminary troubleshooting assistance
This commit is contained in:
@ -148,6 +148,7 @@ MIDDLEWARE = (
|
|||||||
'django.contrib.messages.middleware.MessageMiddleware',
|
'django.contrib.messages.middleware.MessageMiddleware',
|
||||||
'django.middleware.clickjacking.XFrameOptionsMiddleware',
|
'django.middleware.clickjacking.XFrameOptionsMiddleware',
|
||||||
'django.middleware.security.SecurityMiddleware',
|
'django.middleware.security.SecurityMiddleware',
|
||||||
|
'utilities.middleware.ExceptionHandlingMiddleware',
|
||||||
'utilities.middleware.LoginRequiredMiddleware',
|
'utilities.middleware.LoginRequiredMiddleware',
|
||||||
'utilities.middleware.APIVersionMiddleware',
|
'utilities.middleware.APIVersionMiddleware',
|
||||||
)
|
)
|
||||||
|
@ -7,11 +7,10 @@ from django.conf.urls import include, url
|
|||||||
from django.contrib import admin
|
from django.contrib import admin
|
||||||
from django.views.static import serve
|
from django.views.static import serve
|
||||||
|
|
||||||
from netbox.views import APIRootView, handle_500, HomeView, SearchView, trigger_500
|
from netbox.views import APIRootView, HomeView, SearchView
|
||||||
from users.views import LoginView, LogoutView
|
from users.views import LoginView, LogoutView
|
||||||
|
|
||||||
|
|
||||||
handler500 = handle_500
|
|
||||||
swagger_view = get_swagger_view(title='NetBox API')
|
swagger_view = get_swagger_view(title='NetBox API')
|
||||||
|
|
||||||
_patterns = [
|
_patterns = [
|
||||||
@ -48,9 +47,6 @@ _patterns = [
|
|||||||
# Serving static media in Django to pipe it through LoginRequiredMiddleware
|
# Serving static media in Django to pipe it through LoginRequiredMiddleware
|
||||||
url(r'^media/(?P<path>.*)$', serve, {'document_root': settings.MEDIA_ROOT}),
|
url(r'^media/(?P<path>.*)$', serve, {'document_root': settings.MEDIA_ROOT}),
|
||||||
|
|
||||||
# Error testing
|
|
||||||
url(r'^500/$', trigger_500),
|
|
||||||
|
|
||||||
# Admin
|
# Admin
|
||||||
url(r'^admin/', admin.site.urls),
|
url(r'^admin/', admin.site.urls),
|
||||||
|
|
||||||
|
@ -247,23 +247,3 @@ class APIRootView(APIView):
|
|||||||
('tenancy', reverse('tenancy-api:api-root', request=request, format=format)),
|
('tenancy', reverse('tenancy-api:api-root', request=request, format=format)),
|
||||||
('virtualization', reverse('virtualization-api:api-root', request=request, format=format)),
|
('virtualization', reverse('virtualization-api:api-root', request=request, format=format)),
|
||||||
)))
|
)))
|
||||||
|
|
||||||
|
|
||||||
def handle_500(request):
|
|
||||||
"""
|
|
||||||
Custom server error handler
|
|
||||||
"""
|
|
||||||
type_, error, traceback = sys.exc_info()
|
|
||||||
return render(request, '500.html', {
|
|
||||||
'exception': str(type_),
|
|
||||||
'error': error,
|
|
||||||
}, status=500)
|
|
||||||
|
|
||||||
|
|
||||||
def trigger_500(request):
|
|
||||||
"""
|
|
||||||
Hot-wired method of triggering a server error to test reporting
|
|
||||||
"""
|
|
||||||
raise Exception(
|
|
||||||
"Congratulations, you've triggered an exception! Go tell all your friends what an exceptional person you are."
|
|
||||||
)
|
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
<body>
|
<body>
|
||||||
<div class="container-fluid">
|
<div class="container-fluid">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-4 col-md-offset-4">
|
<div class="col-md-6 col-md-offset-3">
|
||||||
<div class="panel panel-danger" style="margin-top: 200px">
|
<div class="panel panel-danger" style="margin-top: 200px">
|
||||||
<div class="panel-heading">
|
<div class="panel-heading">
|
||||||
<strong>
|
<strong>
|
||||||
@ -21,13 +21,20 @@
|
|||||||
</strong>
|
</strong>
|
||||||
</div>
|
</div>
|
||||||
<div class="panel-body">
|
<div class="panel-body">
|
||||||
<p>There was a problem with your request. This error has been logged and administrative staff have
|
{% block message %}
|
||||||
been notified. Please return to the home page and try again.</p>
|
<p>
|
||||||
<p>If you are responsible for this installation, please consider
|
There was a problem with your request. Please contact an administrator.
|
||||||
<a href="https://github.com/digitalocean/netbox/issues">filing a bug report</a>. Additional
|
</p>
|
||||||
information is provided below:</p>
|
{% endblock %}
|
||||||
|
<hr />
|
||||||
|
<p>
|
||||||
|
The complete exception is provided below:
|
||||||
|
</p>
|
||||||
<pre><strong>{{ exception }}</strong><br />
|
<pre><strong>{{ exception }}</strong><br />
|
||||||
{{ error }}</pre>
|
{{ error }}</pre>
|
||||||
|
<p>
|
||||||
|
If further assistance is required, please post to the <a href="https://groups.google.com/forum/#!forum/netbox-discuss">NetBox mailing list</a>.
|
||||||
|
</p>
|
||||||
<div class="text-right">
|
<div class="text-right">
|
||||||
<a href="{% url 'home' %}" class="btn btn-primary">Home Page</a>
|
<a href="{% url 'home' %}" class="btn btn-primary">Home Page</a>
|
||||||
</div>
|
</div>
|
||||||
|
18
netbox/templates/exceptions/import_error.html
Normal file
18
netbox/templates/exceptions/import_error.html
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
{% extends '500.html' %}
|
||||||
|
|
||||||
|
{% block message %}
|
||||||
|
<p>
|
||||||
|
A module import error occurred during this request. Common causes include the following:
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<i class="fa fa-warning"></i> <strong>Missing required packages</strong> - This installation of NetBox might be missing one or more required
|
||||||
|
Python packages. These packages are listed in <code>requirements.txt</code> and are normally installed as part
|
||||||
|
of the installation or upgrade process. To verify installed packages, run <code>pip freeze</code> from the
|
||||||
|
console and compare the output to the list of required packages.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<i class="fa fa-warning"></i> <strong>WSGI service not restarted after upgrade</strong> - If this installation has recently been upgraded,
|
||||||
|
check that the WSGI service (e.g. gunicorn or uWSGI) has been restarted. This ensures that the new code is
|
||||||
|
running.
|
||||||
|
</p>
|
||||||
|
{% endblock %}
|
12
netbox/templates/exceptions/permission_error.html
Normal file
12
netbox/templates/exceptions/permission_error.html
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
{% extends '500.html' %}
|
||||||
|
|
||||||
|
{% block message %}
|
||||||
|
<p>
|
||||||
|
A file permission error was detected while processing this request. Common causes include the following:
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<i class="fa fa-warning"></i> <strong>Insufficient write permission to the media root</strong> - The configured
|
||||||
|
media root is <code>{{ settings.MEDIA_ROOT }}</code>. Ensure that the user NetBox runs as has access to write
|
||||||
|
files to all locations within this path.
|
||||||
|
</p>
|
||||||
|
{% endblock %}
|
17
netbox/templates/exceptions/programming_error.html
Normal file
17
netbox/templates/exceptions/programming_error.html
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
{% extends '500.html' %}
|
||||||
|
|
||||||
|
{% block message %}
|
||||||
|
<p>
|
||||||
|
A database programming error was detected while processing this request. Common causes include the following:
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<i class="fa fa-warning"></i> <strong>Database migrations missing</strong> - When upgrading to a new NetBox release, the upgrade script must
|
||||||
|
be run to apply any new database migrations. You can run migrations manually by executing
|
||||||
|
<code>python3 manage.py migrate</code> from the command line.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<i class="fa fa-warning"></i> <strong>Unsupported PostgreSQL version</strong> - Ensure that PostgreSQL version 9.4 or higher is in use. You
|
||||||
|
can check this by connecting to the database using NetBox's credentials and issuing a query for
|
||||||
|
<code>SELECT VERSION()</code>.
|
||||||
|
</p>
|
||||||
|
{% endblock %}
|
@ -1,7 +1,10 @@
|
|||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
import sys
|
||||||
|
|
||||||
from django.http import HttpResponseRedirect
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
|
from django.db import ProgrammingError
|
||||||
|
from django.http import HttpResponseRedirect
|
||||||
|
from django.shortcuts import render
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
|
|
||||||
|
|
||||||
@ -39,3 +42,38 @@ class APIVersionMiddleware(object):
|
|||||||
if request.path_info.startswith(api_path):
|
if request.path_info.startswith(api_path):
|
||||||
response['API-Version'] = settings.REST_FRAMEWORK_VERSION
|
response['API-Version'] = settings.REST_FRAMEWORK_VERSION
|
||||||
return response
|
return response
|
||||||
|
|
||||||
|
|
||||||
|
class ExceptionHandlingMiddleware(object):
|
||||||
|
"""
|
||||||
|
Intercept certain exceptions which are likely indicative of installation issues and provide helpful instructions
|
||||||
|
to the user.
|
||||||
|
"""
|
||||||
|
def __init__(self, get_response):
|
||||||
|
self.get_response = get_response
|
||||||
|
|
||||||
|
def __call__(self, request):
|
||||||
|
return self.get_response(request)
|
||||||
|
|
||||||
|
def process_exception(self, request, exception):
|
||||||
|
|
||||||
|
# Raise exceptions if in debug mode
|
||||||
|
if settings.DEBUG:
|
||||||
|
raise exception
|
||||||
|
|
||||||
|
# Determine the type of exception
|
||||||
|
if isinstance(exception, ProgrammingError):
|
||||||
|
template_name = 'exceptions/programming_error.html'
|
||||||
|
elif isinstance(exception, ImportError):
|
||||||
|
template_name = 'exceptions/import_error.html'
|
||||||
|
elif isinstance(exception, PermissionError):
|
||||||
|
template_name = 'exceptions/permission_error.html'
|
||||||
|
else:
|
||||||
|
template_name = '500.html'
|
||||||
|
|
||||||
|
# Return an error message
|
||||||
|
type_, error, traceback = sys.exc_info()
|
||||||
|
return render(request, template_name, {
|
||||||
|
'exception': str(type_),
|
||||||
|
'error': error,
|
||||||
|
}, status=500)
|
||||||
|
Reference in New Issue
Block a user