mirror of
https://github.com/netbox-community/netbox.git
synced 2024-05-10 07:54:54 +00:00
Closes #4332: Redirect to a user-friendly error page when CSS/JS resources fail to load
This commit is contained in:
@ -10,6 +10,7 @@
|
|||||||
* [#4323](https://github.com/netbox-community/netbox/issues/4323) - Add bulk edit view for power panels
|
* [#4323](https://github.com/netbox-community/netbox/issues/4323) - Add bulk edit view for power panels
|
||||||
* [#4324](https://github.com/netbox-community/netbox/issues/4324) - Add CSV import view for services
|
* [#4324](https://github.com/netbox-community/netbox/issues/4324) - Add CSV import view for services
|
||||||
* [#4325](https://github.com/netbox-community/netbox/issues/4324) - Add CSV import view for rack reservations
|
* [#4325](https://github.com/netbox-community/netbox/issues/4324) - Add CSV import view for rack reservations
|
||||||
|
* [#4332](https://github.com/netbox-community/netbox/issues/4332) - Redirect to a user-friendly error page when CSS/JS resources fail to load
|
||||||
|
|
||||||
### Bug Fixes
|
### Bug Fixes
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@ from django.views.static import serve
|
|||||||
from drf_yasg import openapi
|
from drf_yasg import openapi
|
||||||
from drf_yasg.views import get_schema_view
|
from drf_yasg.views import get_schema_view
|
||||||
|
|
||||||
from netbox.views import APIRootView, HomeView, SearchView
|
from netbox.views import APIRootView, HomeView, StaticMediaFailureView, SearchView
|
||||||
from users.views import LoginView, LogoutView
|
from users.views import LoginView, LogoutView
|
||||||
from .admin import admin_site
|
from .admin import admin_site
|
||||||
|
|
||||||
@ -63,6 +63,9 @@ _patterns = [
|
|||||||
path('admin/', admin_site.urls),
|
path('admin/', admin_site.urls),
|
||||||
path('admin/webhook-backend-status/', include('django_rq.urls')),
|
path('admin/webhook-backend-status/', include('django_rq.urls')),
|
||||||
|
|
||||||
|
# Errors
|
||||||
|
path('media-failure/', StaticMediaFailureView.as_view(), name='media_failure'),
|
||||||
|
|
||||||
]
|
]
|
||||||
|
|
||||||
if settings.DEBUG:
|
if settings.DEBUG:
|
||||||
|
@ -300,6 +300,16 @@ class SearchView(View):
|
|||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
|
class StaticMediaFailureView(View):
|
||||||
|
"""
|
||||||
|
Display a user-friendly error message with troubleshooting tips when a static media file fails to load.
|
||||||
|
"""
|
||||||
|
def get(self, request):
|
||||||
|
return render(request, 'media_failure.html', {
|
||||||
|
'filename': request.GET.get('filename')
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
class APIRootView(APIView):
|
class APIRootView(APIView):
|
||||||
_ignore_model_permissions = True
|
_ignore_model_permissions = True
|
||||||
exclude_from_schema = True
|
exclude_from_schema = True
|
||||||
|
@ -4,13 +4,27 @@
|
|||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<title>{% block title %}Home{% endblock %} - NetBox</title>
|
<title>{% block title %}Home{% endblock %} - NetBox</title>
|
||||||
<link rel="stylesheet" href="{% static 'bootstrap-3.4.1-dist/css/bootstrap.min.css' %}">
|
<link rel="stylesheet"
|
||||||
<link rel="stylesheet" href="{% static 'font-awesome-4.7.0/css/font-awesome.min.css' %}">
|
href="{% static 'bootstrap-3.4.1-dist/css/bootstrap.min.css' %}"
|
||||||
<link rel="stylesheet" href="{% static 'jquery-ui-1.12.1/jquery-ui.css' %}">
|
onerror="window.location='{% url 'media_failure' %}?filename=bootstrap-3.4.1-dist/css/bootstrap.min.css'">
|
||||||
<link rel="stylesheet" href="{% static 'select2-4.0.12/dist/css/select2.min.css' %}">
|
<link rel="stylesheet"
|
||||||
<link rel="stylesheet" href="{% static 'select2-bootstrap-0.1.0-beta.10/select2-bootstrap.min.css' %}">
|
href="{% static 'font-awesome-4.7.0/css/font-awesome.min.css' %}"
|
||||||
<link rel="stylesheet" href="{% static 'flatpickr-4.6.3/themes/light.css' %}">
|
onerror="window.location='{% url 'media_failure' %}?filename=font-awesome-4.7.0/css/font-awesome.min.css'">
|
||||||
<link rel="stylesheet" href="{% static 'css/base.css' %}?v{{ settings.VERSION }}">
|
<link rel="stylesheet"
|
||||||
|
href="{% static 'jquery-ui-1.12.1/jquery-ui.css' %}"
|
||||||
|
onerror="window.location='{% url 'media_failure' %}?filename=jquery-ui-1.12.1/jquery-ui.css'">
|
||||||
|
<link rel="stylesheet"
|
||||||
|
href="{% static 'select2-4.0.12/dist/css/select2.min.css' %}"
|
||||||
|
onerror="window.location='{% url 'media_failure' %}?filename=select2-4.0.12/dist/css/select2.min.css'">
|
||||||
|
<link rel="stylesheet"
|
||||||
|
href="{% static 'select2-bootstrap-0.1.0-beta.10/select2-bootstrap.min.css' %}"
|
||||||
|
onerror="window.location='{% url 'media_failure' %}?filename=select2-bootstrap-0.1.0-beta.10/select2-bootstrap.min.css'">
|
||||||
|
<link rel="stylesheet"
|
||||||
|
href="{% static 'flatpickr-4.6.3/themes/light.css' %}"
|
||||||
|
onerror="window.location='{% url 'media_failure' %}?filename=flatpickr-4.6.3/themes/light.css'">
|
||||||
|
<link rel="stylesheet"
|
||||||
|
href="{% static 'css/base.css' %}?v{{ settings.VERSION }}"
|
||||||
|
onerror="window.location='{% url 'media_failure' %}?filename=css/base.css'">
|
||||||
<link rel="icon" type="image/png" href="{% static 'img/netbox.ico' %}" />
|
<link rel="icon" type="image/png" href="{% static 'img/netbox.ico' %}" />
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width">
|
<meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width">
|
||||||
@ -66,13 +80,20 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
<script src="{% static 'jquery/jquery-3.4.1.min.js' %}"></script>
|
<script src="{% static 'jquery/jquery-3.4.1.min.js' %}"
|
||||||
<script src="{% static 'jquery-ui-1.12.1/jquery-ui.min.js' %}"></script>
|
onerror="window.location='{% url 'media_failure' %}?filename=jquery/jquery-3.4.1.min.js'"></script>
|
||||||
<script src="{% static 'bootstrap-3.4.1-dist/js/bootstrap.min.js' %}"></script>
|
<script src="{% static 'jquery-ui-1.12.1/jquery-ui.min.js' %}"
|
||||||
<script src="{% static 'select2-4.0.12/dist/js/select2.min.js' %}"></script>
|
onerror="window.location='{% url 'media_failure' %}?filename=jquery-ui-1.12.1/jquery-ui.min.js'"></script>
|
||||||
<script src="{% static 'clipboard.js/clipboard-2.0.4.min.js' %}"></script>
|
<script src="{% static 'bootstrap-3.4.1-dist/js/bootstrap.min.js' %}"
|
||||||
<script src="{% static 'flatpickr-4.6.3/flatpickr.min.js' %}"></script>
|
onerror="window.location='{% url 'media_failure' %}?filename=bootstrap-3.4.1-dist/js/bootstrap.min.js'"></script>
|
||||||
<script src="{% static 'js/forms.js' %}?v{{ settings.VERSION }}"></script>
|
<script src="{% static 'select2-4.0.12/dist/js/select2.min.js' %}"
|
||||||
|
onerror="window.location='{% url 'media_failure' %}?filename=select2-4.0.12/dist/js/select2.min.js'"></script>
|
||||||
|
<script src="{% static 'clipboard.js/clipboard-2.0.4.min.js' %}"
|
||||||
|
onerror="window.location='{% url 'media_failure' %}?filename=clipboard.js/clipboard-2.0.4.min.js'"></script>
|
||||||
|
<script src="{% static 'flatpickr-4.6.3/flatpickr.min.js' %}"
|
||||||
|
onerror="window.location='{% url 'media_failure' %}?filename=flatpickr-4.6.3/flatpickr.min.js'"></script>
|
||||||
|
<script src="{% static 'js/forms.js' %}?v{{ settings.VERSION }}"
|
||||||
|
onerror="window.location='{% url 'media_failure' %}?filename=js/forms.js'"></script>
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
var netbox_api_path = "/{{ settings.BASE_PATH }}api/";
|
var netbox_api_path = "/{{ settings.BASE_PATH }}api/";
|
||||||
var loading = $(".loading");
|
var loading = $(".loading");
|
||||||
|
48
netbox/templates/media_failure.html
Normal file
48
netbox/templates/media_failure.html
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
{% load static %}
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<title>Static Media Failure - NetBox</title>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<style type="text/css">
|
||||||
|
body {
|
||||||
|
font-family: sans-serif;
|
||||||
|
}
|
||||||
|
li.tip {
|
||||||
|
line-height: 150%;
|
||||||
|
margin-bottom: 30px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div style="margin: auto; width: 800px">
|
||||||
|
<h1>Static Media Failure</h1>
|
||||||
|
<h3>
|
||||||
|
The following static media file failed to load:
|
||||||
|
<a href="{% static filename %}"><code style="color: red">{{ filename }}</code></a>
|
||||||
|
</h3>
|
||||||
|
<p>Check the following:</p>
|
||||||
|
<ul>
|
||||||
|
<li class="tip">
|
||||||
|
<code><strong>manage.py collectstatic</strong></code> was run during the most recent upgrade. This installs the most recent
|
||||||
|
iteration of each static file into the static root path.
|
||||||
|
</li>
|
||||||
|
<li class="tip">
|
||||||
|
The HTTP service (e.g. nginx or Apache) is configured to serve files from the <code>STATIC_ROOT</code> path.
|
||||||
|
Refer to <a href="https://netbox.readthedocs.io/en/stable/installation/">the installation
|
||||||
|
documentation</a> for further guidance.
|
||||||
|
<ul>
|
||||||
|
{% if request.user.is_staff or request.user.is_superuser %}
|
||||||
|
<li><code>STATIC_ROOT: <strong>{{ settings.STATIC_ROOT }}</strong></code></li>
|
||||||
|
{% endif %}
|
||||||
|
<li><code>STATIC_URL: <strong>{{ settings.STATIC_URL }}</strong></code></li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
<li class="tip">
|
||||||
|
The file <code>{{ filename }}</code> exists in the static root directory and is readable by the HTTP process.
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<p>Click <a href="/">here</a> to attempt loading NetBox again.</p>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
Reference in New Issue
Block a user