Update default error pages.

This commit is contained in:
Chris Church
2016-02-02 23:00:07 -05:00
parent 4f3dea92fe
commit b08a2d1d88
4 changed files with 82 additions and 38 deletions

View File

@@ -3,33 +3,67 @@
# Django # Django
from django.shortcuts import render from django.shortcuts import render
from django.utils.safestring import mark_safe from django.utils.html import format_html
# Django REST Framework
from rest_framework import exceptions, permissions, views
class ApiErrorView(views.APIView):
authentication_classes = []
permission_classes = (permissions.AllowAny,)
metadata_class = None
allowed_methods = ('GET', 'HEAD')
exception_class = exceptions.APIException
view_name = 'API Error'
def get_view_name(self):
return self.view_name
def get(self, request, format=None):
raise self.exception_class()
def handle_error(request, status=404, **kwargs): def handle_error(request, status=404, **kwargs):
# FIXME: Should attempt to check HTTP Accept request header and return # For errors to /api/*, use a simple DRF view/exception to generate a
# plain JSON response instead of HTML (maybe only for /api/*). # browsable error page for browser clients or a simple JSON response for any
context = kwargs # other clients.
# Return enough context to popuplate the base API template. if request.path.startswith('/api/'):
description = u'<pre class="err">%s</pre>' % context.get('content', '') class APIException(exceptions.APIException):
context['description'] = mark_safe(description) status_code = status
context['content'] = '' default_detail = kwargs['content']
template_name = 'error.html' api_error_view = ApiErrorView.as_view(view_name=kwargs['name'], exception_class=APIException)
return render(request, template_name, context, status=status) return api_error_view(request)
else:
kwargs['content'] = format_html('<span class="nocode">{}</span>', kwargs.get('content', ''))
return render(request, 'error.html', kwargs, status=status)
def handle_400(request):
kwargs = {
'name': 'Bad Request',
'content': 'The request could not be understood by the server.',
}
return handle_error(request, 400, **kwargs)
def handle_403(request): def handle_403(request):
kwargs = { kwargs = {
'name': 'Forbidden', 'name': 'Forbidden',
'content': 'You don\'t have permission to access the requested page.', 'content': 'You don\'t have permission to access the requested resource.',
} }
return handle_error(request, 403, **kwargs) return handle_error(request, 403, **kwargs)
def handle_404(request): def handle_404(request):
kwargs = { kwargs = {
'name': 'Not Found', 'name': 'Not Found',
'content': 'The requested page could not be found.', 'content': 'The requested resource could not be found.',
} }
return handle_error(request, 404, **kwargs) return handle_error(request, 404, **kwargs)
def handle_500(request): def handle_500(request):
kwargs = { kwargs = {
'name': 'Server Error', 'name': 'Server Error',

View File

@@ -203,5 +203,6 @@ body #footer .footer-copyright a {
text-align: center; text-align: center;
padding-right: 15px; padding-right: 15px;
padding-top: 0; padding-top: 0;
white-space: nowrap;
} }
} }

View File

@@ -1,28 +1,31 @@
{% extends "rest_framework/api.html" %} {% extends "rest_framework/api.html" %}
{% load i18n %} {% load i18n staticfiles %}
{% block title %}{{ name }} &middot; {% trans 'Ansible Tower' %}{% endblock %}
{% block style %} {% block style %}
{{ block.super }} {{ block.super }}
<style type="text/css"> <style type="text/css">
ul.breadcrumb { div.request-info,
visibility: hidden; div.response-info span.meta {
margin-top: 10px !important;
}
pre.err {
margin-bottom: 2em;
}
div.request-info, div.response-info {
display: none; display: none;
} }
</style> </style>
{% endblock %} {% endblock %}
{% block branding_title %}{% endblock %} {% block navbar %}
<div class="navbar navbar-fixed-top">
{% block breadcrumbs %} <div class="container">
<ul class="breadcrumb"> <div class="navbar-header">
<li> <a class="navbar-brand" href="/">
<a href="{{ request.get_full_path }}" class="active">{{ name }}</a> <img class="logo" src="{% static 'assets/main_menu_logo.png' %}">
</li> </a>
</ul> <a class="navbar-title" href="{{ request.get_full_path }}">
<span>&nbsp;&mdash; {{name}}</span>
</a>
</div>
</div>
</div>
{% endblock %} {% endblock %}
{% block breadcrumbs %}{% endblock %}

View File

@@ -3,17 +3,23 @@
from django.conf.urls import url, patterns, include from django.conf.urls import url, patterns, include
handler400 = 'awx.main.views.handle_400'
handler403 = 'awx.main.views.handle_403' handler403 = 'awx.main.views.handle_403'
handler404 = 'awx.main.views.handle_404' handler404 = 'awx.main.views.handle_404'
handler500 = 'awx.main.views.handle_500' handler500 = 'awx.main.views.handle_500'
urlpatterns = patterns('', urlpatterns = patterns(
url(r'', include('awx.ui.urls', namespace='ui', app_name='ui')), '',
url(r'^api/', include('awx.api.urls', namespace='api', app_name='api')), url(r'', include('awx.ui.urls', namespace='ui', app_name='ui')),
url(r'^sso/', include('awx.sso.urls', namespace='sso', app_name='sso')), url(r'^api/', include('awx.api.urls', namespace='api', app_name='api')),
url(r'^sso/', include('social.apps.django_app.urls', namespace='social'))) url(r'^sso/', include('awx.sso.urls', namespace='sso', app_name='sso')),
url(r'^sso/', include('social.apps.django_app.urls', namespace='social')),
)
urlpatterns += patterns('awx.main.views', urlpatterns += patterns(
url(r'^403.html$', 'handle_403'), 'awx.main.views',
url(r'^404.html$', 'handle_404'), url(r'^(?:api/)?400.html$', 'handle_400'),
url(r'^500.html$', 'handle_500')) url(r'^(?:api/)?403.html$', 'handle_403'),
url(r'^(?:api/)?404.html$', 'handle_404'),
url(r'^(?:api/)?500.html$', 'handle_500'),
)