diff --git a/awx/api/views.py b/awx/api/views.py index 272983cb2b..05a42d512b 100644 --- a/awx/api/views.py +++ b/awx/api/views.py @@ -12,18 +12,20 @@ from django.conf import settings from django.contrib.auth.models import User from django.core.urlresolvers import reverse from django.db.models import Q +from django.db import IntegrityError from django.shortcuts import get_object_or_404 from django.utils.datastructures import SortedDict from django.utils.timezone import now # Django REST Framework from rest_framework.authtoken.views import ObtainAuthToken -from rest_framework.exceptions import PermissionDenied +from rest_framework.exceptions import PermissionDenied, ParseError from rest_framework.parsers import YAMLParser from rest_framework.permissions import AllowAny, IsAuthenticated from rest_framework.renderers import YAMLRenderer from rest_framework.response import Response from rest_framework.settings import api_settings +from rest_framework.views import exception_handler from rest_framework import status # AWX @@ -36,6 +38,15 @@ from awx.api.serializers import * from awx.api.generics import * +def api_exception_handler(exc): + ''' + Override default API exception handler to catch IntegrityError exceptions. + ''' + if isinstance(exc, IntegrityError): + exc = ParseError(exc.args[0]) + return exception_handler(exc) + + class ApiRootView(APIView): permission_classes = (AllowAny,) diff --git a/awx/main/tests/projects.py b/awx/main/tests/projects.py index 5eea15ce69..c5c1151715 100644 --- a/awx/main/tests/projects.py +++ b/awx/main/tests/projects.py @@ -499,6 +499,12 @@ class ProjectsTest(BaseTest): with self.current_user(self.super_django_user): data = dict(name='xyz', user=self.super_django_user.pk) self.post(url, data, expect=400) + + # Test with null where we expect a string value. + with self.current_user(self.super_django_user): + data = dict(name='zyx', user=self.super_django_user.pk, kind='ssh', + sudo_username=None) + self.post(url, data, expect=400) # FIXME: Check list as other users. diff --git a/awx/main/views.py b/awx/main/views.py index ccced20438..cc487ee4ed 100644 --- a/awx/main/views.py +++ b/awx/main/views.py @@ -2,18 +2,16 @@ # All Rights Reserved. # Django -from django.shortcuts import render_to_response +from django.shortcuts import render from django.template import RequestContext def handle_error(request, status=404): context = {} - #print request.path, status if request.path.startswith('/admin/'): template_name = 'admin/%d.html' % status else: template_name = '%d.html' % status - return render_to_response(template_name, context, - context_instance=RequestContext(request)) + return render(request, template_name, context, status=status) def handle_403(request): return handle_error(request, 403) diff --git a/awx/settings/defaults.py b/awx/settings/defaults.py index c9bdbe73e1..dac6a86714 100644 --- a/awx/settings/defaults.py +++ b/awx/settings/defaults.py @@ -163,6 +163,7 @@ REST_FRAMEWORK = { 'rest_framework.renderers.JSONRenderer', 'awx.api.renderers.BrowsableAPIRenderer', ), + 'EXCEPTION_HANDLER': 'awx.api.views.api_exception_handler', 'VIEW_NAME_FUNCTION': 'awx.api.generics.get_view_name', 'VIEW_DESCRIPTION_FUNCTION': 'awx.api.generics.get_view_description', }