diff --git a/nova/api/openstack/wsgi.py b/nova/api/openstack/wsgi.py index 706ac603d6e3..8cee8f769a7c 100644 --- a/nova/api/openstack/wsgi.py +++ b/nova/api/openstack/wsgi.py @@ -29,6 +29,7 @@ from nova.api import wsgi from nova import exception from nova import i18n from nova.i18n import _ +from nova import version LOG = logging.getLogger(__name__) @@ -683,9 +684,10 @@ def expected_errors(errors): raise LOG.exception("Unexpected exception in API method") - msg = _('Unexpected API Error. Please report this at ' - 'http://bugs.launchpad.net/nova/ and attach the Nova ' - 'API log if possible.\n%s') % type(exc) + msg = _("Unexpected API Error. " + "%(support)s\n%(exc)s" % { + 'support': version.support_string(), + 'exc': type(exc)}) raise webob.exc.HTTPInternalServerError(explanation=msg) return wrapped diff --git a/nova/tests/unit/test_versions.py b/nova/tests/unit/test_versions.py index 86522de2566f..d1f700f01817 100644 --- a/nova/tests/unit/test_versions.py +++ b/nova/tests/unit/test_versions.py @@ -34,7 +34,8 @@ class VersionTestCase(test.NoDBTestCase): "[Nova]\n" "vendor = ACME Corporation\n" "product = ACME Nova\n" - "package = 1337\n") + "package = 1337\n" + "support = Contact ACME support\n") def test_release_file(self): version.loaded = False real_find_file = cfg.CONF.find_file @@ -49,3 +50,4 @@ class VersionTestCase(test.NoDBTestCase): self.assertEqual(version.vendor_string(), "ACME Corporation") self.assertEqual(version.product_string(), "ACME Nova") self.assertEqual(version.package_string(), "1337") + self.assertEqual(version.support_string(), "Contact ACME support") diff --git a/nova/version.py b/nova/version.py index 1ec746133929..e3282f72f6b1 100644 --- a/nova/version.py +++ b/nova/version.py @@ -17,6 +17,9 @@ import pbr.version NOVA_VENDOR = "OpenStack Foundation" NOVA_PRODUCT = "OpenStack Nova" NOVA_PACKAGE = None # OS distro package version suffix +NOVA_SUPPORT = ( + "Please report this at http://bugs.launchpad.net/nova/ " + "and attach the Nova API log if possible.") loaded = False version_info = pbr.version.VersionInfo('nova') @@ -33,7 +36,7 @@ def _load_config(): from oslo_log import log as logging - global loaded, NOVA_VENDOR, NOVA_PRODUCT, NOVA_PACKAGE + global loaded, NOVA_VENDOR, NOVA_PRODUCT, NOVA_PACKAGE, NOVA_SUPPORT if loaded: return @@ -55,6 +58,9 @@ def _load_config(): if cfg.has_option("Nova", "package"): NOVA_PACKAGE = cfg.get("Nova", "package") + + if cfg.has_option("Nova", "support"): + NOVA_SUPPORT = cfg.get("Nova", "support") except Exception as ex: LOG = logging.getLogger(__name__) LOG.error("Failed to load %(cfgfile)s: %(ex)s", @@ -84,3 +90,9 @@ def version_string_with_package(): return version_info.version_string() else: return "%s-%s" % (version_info.version_string(), package_string()) + + +def support_string(): + _load_config() + + return NOVA_SUPPORT diff --git a/releasenotes/notes/custom-api-unexpected-exception-1bfc5e174ee5b6a7.yaml b/releasenotes/notes/custom-api-unexpected-exception-1bfc5e174ee5b6a7.yaml new file mode 100644 index 000000000000..fc722f213add --- /dev/null +++ b/releasenotes/notes/custom-api-unexpected-exception-1bfc5e174ee5b6a7.yaml @@ -0,0 +1,7 @@ +--- +features: + - | + The "API unexpected exception" message can now be configured by the cloud + provider to point to a custom support page. + By default it continues to show "http://bugs.launchpad.net/nova/". + It can be configured using the release file.