Skip to content

Commit d28c5bc

Browse files
committed
Improve HTTP error formatting
This improves formatting for HTTP errors. keystoneauth's HttpErrors are now caught an re-formatted to include the body of the http response. Work items: * Introduce the "http_error_formatter" function decorator, which catches an re-formats keystoneauths HttpErrors. * Introduce the "format_http_errors" class decorator, which applies the "http_error_formatter" to all functions of a class. * Add an "HttpDecoratorMeta" to the "BaseManager" class. This will decorate all functions of classes inheriting from "BaseManager" with the "http_error_formatter" decorator. Change-Id: I6735f1fa8d876a87e2b7d4aaa533d5a32b085735
1 parent 3e7f7a0 commit d28c5bc

2 files changed

Lines changed: 59 additions & 1 deletion

File tree

cloudkittyclient/common/base.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,23 @@
1515
#
1616
from string import Formatter as StringFormatter
1717

18+
from six import add_metaclass
1819
from six.moves.urllib.parse import urlencode
1920

21+
from cloudkittyclient import utils
2022

23+
24+
class HttpDecoratorMeta(type):
25+
26+
ignore = ('get_url', )
27+
28+
def __new__(cls, *args, **kwargs):
29+
return utils.format_http_errors(HttpDecoratorMeta.ignore)(
30+
super(HttpDecoratorMeta, cls).__new__(cls, *args, **kwargs)
31+
)
32+
33+
34+
@add_metaclass(HttpDecoratorMeta)
2135
class BaseManager(object):
2236
"""Base class for Endpoint Manager objects."""
2337

cloudkittyclient/utils.py

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
# -*- coding: utf-8 -*-
21
# Copyright 2018 Objectif Libre
32
#
43
# Licensed under the Apache License, Version 2.0 (the "License"); you may
@@ -13,8 +12,12 @@
1312
# License for the specific language governing permissions and limitations
1413
# under the License.
1514
#
15+
import inspect
16+
import sys
17+
1618
import pbr.version
1719

20+
from keystoneauth1.exceptions import http
1821
from oslo_utils import timeutils
1922

2023

@@ -56,3 +59,44 @@ def list_to_cols(list_obj, cols):
5659
for item in list_obj:
5760
values.append(dict_to_cols(item, cols))
5861
return values
62+
63+
64+
def http_error_formatter(func):
65+
"""This decorator catches Http Errors and re-formats them"""
66+
67+
def wrap(*args, **kwargs):
68+
try:
69+
return func(*args, **kwargs)
70+
except http.HttpError as e:
71+
raise http.HttpError(message=e.response.text,
72+
http_status=e.http_status)
73+
74+
return wrap
75+
76+
77+
def format_http_errors(ignore):
78+
"""Applies ``http_error_formatter`` to all methods of a class.
79+
80+
:param ignore: List of function names to ignore
81+
:type ignore: iterable
82+
"""
83+
84+
def wrap(cls):
85+
# If you want pretty errors, use python3.
86+
# __qualname__ does not exist in python 2
87+
if sys.version_info.major < 3:
88+
return cls
89+
90+
def predicate(item):
91+
# This avoids decorating functions of parent classes
92+
return (inspect.isfunction(item)
93+
and item.__name__ not in ignore
94+
and not item.__name__.startswith('_')
95+
and cls.__name__ in item.__qualname__)
96+
97+
for name, func in inspect.getmembers(cls, predicate):
98+
setattr(cls, name, http_error_formatter(func))
99+
100+
return cls
101+
102+
return wrap

0 commit comments

Comments
 (0)