Skip to content

Commit

Permalink
Revert "Refactoring the exceptions lists"
Browse files Browse the repository at this point in the history
This reverts commit 7fc1baa.

Change-Id: I495e76eea8c873d71b37625b0953d821156c599c
Closes-Bug: 1440903
  • Loading branch information
Doug Fish committed Apr 6, 2015
1 parent da433ef commit 3531d7b
Show file tree
Hide file tree
Showing 9 changed files with 121 additions and 150 deletions.
6 changes: 6 additions & 0 deletions horizon/conf/__init__.py
Expand Up @@ -23,6 +23,12 @@ def _setup(self, name=None):
HORIZON_CONFIG = copy.copy(DEFAULT_CONFIG)
HORIZON_CONFIG.update(settings.HORIZON_CONFIG)

# Ensure we always have our exception configuration...
for exc_category in ['unauthorized', 'not_found', 'recoverable']:
if exc_category not in HORIZON_CONFIG['exceptions']:
default_exc_config = DEFAULT_CONFIG['exceptions'][exc_category]
HORIZON_CONFIG['exceptions'][exc_category] = default_exc_config

# Ensure our password validator always exists...
if 'regex' not in HORIZON_CONFIG['password_validator']:
default_pw_regex = DEFAULT_CONFIG['password_validator']['regex']
Expand Down
5 changes: 5 additions & 0 deletions horizon/conf/default.py
Expand Up @@ -31,6 +31,11 @@
# URL for additional help with this site.
'help_url': None,

# Exception configuration.
'exceptions': {'unauthorized': [],
'not_found': [],
'recoverable': []},

# Password configuration.
'password_validator': {'regex': '.*',
'help_text': _("Password is not accepted")},
Expand Down
28 changes: 14 additions & 14 deletions horizon/exceptions.py
Expand Up @@ -22,14 +22,14 @@

import six

from django.conf import settings
from django.core.management import color_style # noqa
from django.http import HttpRequest # noqa
from django.utils import encoding
from django.utils.translation import ugettext_lazy as _
from django.views.debug import CLEANSED_SUBSTITUTE # noqa
from django.views.debug import SafeExceptionReporterFilter # noqa

from horizon.conf import HORIZON_CONFIG # noqa
from horizon import messages

LOG = logging.getLogger(__name__)
Expand Down Expand Up @@ -202,6 +202,12 @@ def __init__(self, wrapped):
self.wrapped = wrapped


UNAUTHORIZED = tuple(HORIZON_CONFIG['exceptions']['unauthorized'])
NOT_FOUND = tuple(HORIZON_CONFIG['exceptions']['not_found'])
RECOVERABLE = (AlreadyExists, Conflict, NotAvailable, ServiceCatalogException)
RECOVERABLE += tuple(HORIZON_CONFIG['exceptions']['recoverable'])


def error_color(msg):
return color_style().ERROR_OUTPUT(msg)

Expand Down Expand Up @@ -274,6 +280,13 @@ def handle_recoverable(request, message, redirect, ignore, escalate, handled,
return RecoverableError # return to normal code flow


HANDLE_EXC_METHODS = [
{'exc': UNAUTHORIZED, 'handler': handle_unauthorized, 'set_wrap': False},
{'exc': NOT_FOUND, 'handler': handle_notfound, 'set_wrap': True},
{'exc': RECOVERABLE, 'handler': handle_recoverable, 'set_wrap': True},
]


def handle(request, message=None, redirect=None, ignore=False,
escalate=False, log_level=None, force_log=None):
"""Centralized error handling for Horizon.
Expand Down Expand Up @@ -303,19 +316,6 @@ def handle(request, message=None, redirect=None, ignore=False,
class indicating the type of exception that was encountered will be
returned.
"""
HORIZON_CONFIG = settings.HORIZON_CONFIG
UNAUTHORIZED = tuple(HORIZON_CONFIG['exceptions']['unauthorized'])
NOT_FOUND = tuple(HORIZON_CONFIG['exceptions']['not_found'])
RECOVERABLE = (AlreadyExists, Conflict, NotAvailable,
ServiceCatalogException)
RECOVERABLE += tuple(HORIZON_CONFIG['exceptions']['recoverable'])
HANDLE_EXC_METHODS = [
{'exc': UNAUTHORIZED, 'handler': handle_unauthorized,
'set_wrap': False},
{'exc': NOT_FOUND, 'handler': handle_notfound, 'set_wrap': True},
{'exc': RECOVERABLE, 'handler': handle_recoverable, 'set_wrap': True}
]

exc_type, exc_value, exc_traceback = sys.exc_info()
log_method = getattr(LOG, log_level or "exception")
force_log = force_log or os.environ.get("HORIZON_TEST_RUN", False)
Expand Down
42 changes: 0 additions & 42 deletions horizon/test/settings.py
Expand Up @@ -20,17 +20,6 @@
import socket
import sys

from cinderclient import exceptions as cinderclient
from glanceclient.common import exceptions as glanceclient
from heatclient import exc as heatclient
from keystoneclient import exceptions as keystoneclient
from neutronclient.common import exceptions as neutronclient
from novaclient import exceptions as novaclient
from requests import exceptions as requests
from saharaclient.api import base as saharaclient
from swiftclient import client as swiftclient
from troveclient import exceptions as troveclient

import django
from django.utils import html_parser
from openstack_dashboard.static_settings import get_staticfiles_dirs # noqa
Expand Down Expand Up @@ -146,37 +135,6 @@
},
'user_home': None,
'help_url': "http://example.com",
'exceptions': {'recoverable': (keystoneclient.ClientException,
keystoneclient.AuthorizationFailure,
keystoneclient.Forbidden,
cinderclient.ClientException,
cinderclient.ConnectionError,
cinderclient.Forbidden,
novaclient.ClientException,
novaclient.Forbidden,
glanceclient.ClientException,
neutronclient.Forbidden,
neutronclient.NeutronClientException,
swiftclient.ClientException,
heatclient.HTTPForbidden,
heatclient.HTTPException,
troveclient.ClientException,
saharaclient.APIException,
requests.RequestException),
'not_found': (keystoneclient.NotFound,
cinderclient.NotFound,
novaclient.NotFound,
glanceclient.NotFound,
neutronclient.NotFound,
heatclient.HTTPNotFound,
troveclient.NotFound),
'unauthorized': (keystoneclient.Unauthorized,
cinderclient.Unauthorized,
novaclient.Unauthorized,
glanceclient.Unauthorized,
neutronclient.Unauthorized,
heatclient.HTTPUnauthorized,
troveclient.Unauthorized)}
}

COMPRESS_ENABLED = True
Expand Down
18 changes: 11 additions & 7 deletions openstack_dashboard/api/rest/utils.py
Expand Up @@ -12,7 +12,6 @@
# See the License for the specific language governing permissions and
# limitations under the License.
import functools
import itertools
import json
import logging

Expand All @@ -22,6 +21,7 @@

from oslo_serialization import jsonutils

from horizon import exceptions

log = logging.getLogger(__name__)

Expand All @@ -31,6 +31,9 @@ def __init__(self, http_status, msg):
self.http_status = http_status
super(AjaxError, self).__init__(msg)

http_errors = exceptions.UNAUTHORIZED + exceptions.NOT_FOUND + \
exceptions.RECOVERABLE + (AjaxError, )


class CreatedResponse(http.HttpResponse):
def __init__(self, location, data=None):
Expand Down Expand Up @@ -107,24 +110,25 @@ def _wrapped(self, request, *args, **kw):
return JSONResponse('request requires JSON body', 400)

# invoke the wrapped function, handling exceptions sanely
horizon_exc = settings.HORIZON_CONFIG['exceptions'].values()
api_exc = itertools.chain([AjaxError, ], *horizon_exc)
try:
data = function(self, request, *args, **kw)
if isinstance(data, http.HttpResponse):
return data
elif data is None:
return JSONResponse('', status=204)
return JSONResponse(data)
except tuple(api_exc) as e:
except http_errors as e:
# exception was raised with a specific HTTP status
if hasattr(e, 'http_status'):
http_status = e.http_status
elif hasattr(e, 'code'):
http_status = e.code
else:
http_status = getattr(e, 'code', 500)
log.exception('API Error: %s', e)
log.exception('HTTP exception with no status/code')
return JSONResponse(str(e), 500)
return JSONResponse(str(e), http_status)
except Exception as e:
log.exception('Internal Error: %s', e)
log.exception('error invoking apiclient')
return JSONResponse(str(e), 500)

return _wrapped
Expand Down
73 changes: 73 additions & 0 deletions openstack_dashboard/exceptions.py
@@ -0,0 +1,73 @@
# Copyright 2012 United States Government as represented by the
# Administrator of the National Aeronautics and Space Administration.
# All Rights Reserved.
#
# Copyright 2012 Nebula, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.

from cinderclient import exceptions as cinderclient
from glanceclient.common import exceptions as glanceclient
from heatclient import exc as heatclient
from keystoneclient import exceptions as keystoneclient
from neutronclient.common import exceptions as neutronclient
from novaclient import exceptions as novaclient
from requests import exceptions as requests
from saharaclient.api import base as saharaclient
from swiftclient import client as swiftclient
from troveclient import exceptions as troveclient


UNAUTHORIZED = (
keystoneclient.Unauthorized,
cinderclient.Unauthorized,
novaclient.Unauthorized,
glanceclient.Unauthorized,
neutronclient.Unauthorized,
heatclient.HTTPUnauthorized,
troveclient.Unauthorized,
)


NOT_FOUND = (
keystoneclient.NotFound,
cinderclient.NotFound,
novaclient.NotFound,
glanceclient.NotFound,
neutronclient.NotFound,
heatclient.HTTPNotFound,
troveclient.NotFound,
)


# NOTE(gabriel): This is very broad, and may need to be dialed in.
RECOVERABLE = (
keystoneclient.ClientException,
# AuthorizationFailure is raised when Keystone is "unavailable".
keystoneclient.AuthorizationFailure,
keystoneclient.Forbidden,
cinderclient.ClientException,
cinderclient.ConnectionError,
cinderclient.Forbidden,
novaclient.ClientException,
novaclient.Forbidden,
glanceclient.ClientException,
neutronclient.Forbidden,
neutronclient.NeutronClientException,
swiftclient.ClientException,
heatclient.HTTPForbidden,
heatclient.HTTPException,
troveclient.ClientException,
saharaclient.APIException,
requests.RequestException,
)
7 changes: 4 additions & 3 deletions openstack_dashboard/local/local_settings.py.example
Expand Up @@ -2,6 +2,7 @@ import os

from django.utils.translation import ugettext_lazy as _

from openstack_dashboard import exceptions

DEBUG = True
TEMPLATE_DEBUG = DEBUG
Expand Down Expand Up @@ -73,9 +74,9 @@ HORIZON_CONFIG = {
'types': ['alert-success', 'alert-info']
},
'help_url': "http://docs.openstack.org",
'exceptions': {'recoverable': [],
'not_found': [],
'unauthorized': []},
'exceptions': {'recoverable': exceptions.RECOVERABLE,
'not_found': exceptions.NOT_FOUND,
'unauthorized': exceptions.UNAUTHORIZED},
'modal_backdrop': 'static',
'angular_modules': [],
'js_files': [],
Expand Down
46 changes: 4 additions & 42 deletions openstack_dashboard/settings.py
Expand Up @@ -21,20 +21,10 @@
import sys
import warnings

from cinderclient import exceptions as cinderclient
from glanceclient.common import exceptions as glanceclient
from heatclient import exc as heatclient
from keystoneclient import exceptions as keystoneclient
from neutronclient.common import exceptions as neutronclient
from novaclient import exceptions as novaclient
from requests import exceptions as requests
from saharaclient.api import base as saharaclient
from swiftclient import client as swiftclient
from troveclient import exceptions as troveclient

import django
from django.utils.translation import ugettext_lazy as _

from openstack_dashboard import exceptions
from openstack_dashboard.static_settings import get_staticfiles_dirs # noqa


Expand Down Expand Up @@ -69,37 +59,9 @@
'types': ['alert-success', 'alert-info']
},
'help_url': "http://docs.openstack.org",
'exceptions': {'recoverable': (keystoneclient.ClientException,
keystoneclient.AuthorizationFailure,
keystoneclient.Forbidden,
cinderclient.ClientException,
cinderclient.ConnectionError,
cinderclient.Forbidden,
novaclient.ClientException,
novaclient.Forbidden,
glanceclient.ClientException,
neutronclient.Forbidden,
neutronclient.NeutronClientException,
swiftclient.ClientException,
heatclient.HTTPForbidden,
heatclient.HTTPException,
troveclient.ClientException,
saharaclient.APIException,
requests.RequestException),
'not_found': (keystoneclient.NotFound,
cinderclient.NotFound,
novaclient.NotFound,
glanceclient.NotFound,
neutronclient.NotFound,
heatclient.HTTPNotFound,
troveclient.NotFound),
'unauthorized': (keystoneclient.Unauthorized,
cinderclient.Unauthorized,
novaclient.Unauthorized,
glanceclient.Unauthorized,
neutronclient.Unauthorized,
heatclient.HTTPUnauthorized,
troveclient.Unauthorized)},
'exceptions': {'recoverable': exceptions.RECOVERABLE,
'not_found': exceptions.NOT_FOUND,
'unauthorized': exceptions.UNAUTHORIZED},
'angular_modules': [],
'js_files': [],
'js_spec_files': [],
Expand Down

0 comments on commit 3531d7b

Please sign in to comment.