Set 'code' in error response

Run this command:

$ zun --debug show non-existing-container
...
RESP BODY: {"errors": [{"status": 404, "code": "", "links": [], "title":
"Container non-existing-container could not be found.", "detail": "Container
non-existing-container could not be found.", "request_id": "}]}
...

As showed above, the "code" is empty because Zun doesn't pass 'faultcode'.
This patch will add 'faultcode' and set 'code' in error response which
follow convention in [1]

[1] https://specs.openstack.org/openstack/api-wg/guidelines/errors.html

Change-Id: Ic95d70756c91027cbfcc28cfea41c3f34787c177
Closes-Bug: #1685571
This commit is contained in:
Kien Nguyen 2017-10-18 14:55:31 +07:00
parent 242e9b5017
commit f843513137
2 changed files with 19 additions and 3 deletions

View File

@ -26,6 +26,7 @@ from zun.common.i18n import _
class ParsableErrorMiddleware(object):
"""Replace error body with something the client can parse."""
def __init__(self, app):
self.app = app
@ -74,7 +75,11 @@ class ParsableErrorMiddleware(object):
title = ''
desc = ''
code = err['faultcode'].lower() if 'faultcode' in err else ''
error_code = err['faultstring'].lower() \
if 'faultstring' in err else ''
# 'container' is the service-name. The general form of the
# code is service-name.error-code.
code = '.'.join(['container', error_code])
errs.append({
'request_id': '',

View File

@ -20,16 +20,17 @@ Includes decorator for re-raising Zun-type exceptions.
import functools
import inspect
from oslo_utils import uuidutils
import re
import sys
from webob import util as woutil
from keystoneclient import exceptions as keystone_exceptions
from oslo_config import cfg
from oslo_log import log as logging
from oslo_utils import excutils
from oslo_utils import uuidutils
import pecan
import six
from webob import util as woutil
from zun.common.i18n import _
import zun.conf
@ -129,11 +130,19 @@ def wrap_controller_exception(func, func_server_error, func_client_error):
return wrapped
def convert_excp_to_err_code(excp_name):
"""Convert Exception class name (CamelCase) to error-code (Snake-case)"""
words = re.findall(r'[A-Z]?[a-z]+|[A-Z]{2,}(?=[A-Z][a-z]|\d|\W|$)|\d+',
excp_name)
return '-'.join([str.lower(word) for word in words])
def wrap_pecan_controller_exception(func):
"""This decorator wraps pecan controllers to handle exceptions."""
def _func_server_error(log_correlation_id, status_code):
pecan.response.status = status_code
return {
'faultcode': 'Server',
'status_code': status_code,
'title': woutil.status_reasons[status_code],
'description': six.text_type(OBFUSCATED_MSG % log_correlation_id),
@ -142,6 +151,8 @@ def wrap_pecan_controller_exception(func):
def _func_client_error(excp, status_code):
pecan.response.status = status_code
return {
'faultcode': 'Client',
'faultstring': convert_excp_to_err_code(excp.__class__.__name__),
'status_code': status_code,
'title': six.text_type(excp),
'description': six.text_type(excp),