From b08a2d1d88c35e17568b96dddab0a0fb3973b256 Mon Sep 17 00:00:00 2001 From: Chris Church Date: Tue, 2 Feb 2016 23:00:07 -0500 Subject: [PATCH] Update default error pages. --- awx/main/views.py | 58 +++++++++++++++++++++++++++++++--------- awx/static/api/api.css | 1 + awx/templates/error.html | 37 +++++++++++++------------ awx/urls.py | 24 ++++++++++------- 4 files changed, 82 insertions(+), 38 deletions(-) diff --git a/awx/main/views.py b/awx/main/views.py index eda97590a5..5720405093 100644 --- a/awx/main/views.py +++ b/awx/main/views.py @@ -3,33 +3,67 @@ # Django 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): - # FIXME: Should attempt to check HTTP Accept request header and return - # plain JSON response instead of HTML (maybe only for /api/*). - context = kwargs - # Return enough context to popuplate the base API template. - description = u'
%s
' % context.get('content', '') - context['description'] = mark_safe(description) - context['content'] = '' - template_name = 'error.html' - return render(request, template_name, context, status=status) + # For errors to /api/*, use a simple DRF view/exception to generate a + # browsable error page for browser clients or a simple JSON response for any + # other clients. + if request.path.startswith('/api/'): + class APIException(exceptions.APIException): + status_code = status + default_detail = kwargs['content'] + api_error_view = ApiErrorView.as_view(view_name=kwargs['name'], exception_class=APIException) + return api_error_view(request) + else: + kwargs['content'] = format_html('{}', 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): kwargs = { '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) + def handle_404(request): kwargs = { '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) + def handle_500(request): kwargs = { 'name': 'Server Error', diff --git a/awx/static/api/api.css b/awx/static/api/api.css index b168ebd0d1..0a297f5b89 100644 --- a/awx/static/api/api.css +++ b/awx/static/api/api.css @@ -203,5 +203,6 @@ body #footer .footer-copyright a { text-align: center; padding-right: 15px; padding-top: 0; + white-space: nowrap; } } diff --git a/awx/templates/error.html b/awx/templates/error.html index 660740ce52..7064b8687c 100644 --- a/awx/templates/error.html +++ b/awx/templates/error.html @@ -1,28 +1,31 @@ {% extends "rest_framework/api.html" %} -{% load i18n %} +{% load i18n staticfiles %} + +{% block title %}{{ name }} · {% trans 'Ansible Tower' %}{% endblock %} {% block style %} {{ block.super }} {% endblock %} -{% block branding_title %}{% endblock %} - -{% block breadcrumbs %} - +{% block navbar %} + {% endblock %} + +{% block breadcrumbs %}{% endblock %} diff --git a/awx/urls.py b/awx/urls.py index f24ae22e58..27d81416dd 100644 --- a/awx/urls.py +++ b/awx/urls.py @@ -3,17 +3,23 @@ from django.conf.urls import url, patterns, include +handler400 = 'awx.main.views.handle_400' handler403 = 'awx.main.views.handle_403' handler404 = 'awx.main.views.handle_404' handler500 = 'awx.main.views.handle_500' -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'^sso/', include('awx.sso.urls', namespace='sso', app_name='sso')), - url(r'^sso/', include('social.apps.django_app.urls', namespace='social'))) +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'^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', - url(r'^403.html$', 'handle_403'), - url(r'^404.html$', 'handle_404'), - url(r'^500.html$', 'handle_500')) +urlpatterns += patterns( + 'awx.main.views', + url(r'^(?:api/)?400.html$', 'handle_400'), + url(r'^(?:api/)?403.html$', 'handle_403'), + url(r'^(?:api/)?404.html$', 'handle_404'), + url(r'^(?:api/)?500.html$', 'handle_500'), +)