Statistics
| Branch: | Tag: | Revision:

root / kamaki / clients / commissioning / exception.py @ 2005b18e

History | View | Annotate | Download (3.9 kB)

1
# Copyright 2012 GRNET S.A. All rights reserved.
2
#
3
# Redistribution and use in source and binary forms, with or
4
# without modification, are permitted provided that the following
5
# conditions are met:
6
#
7
#   1. Redistributions of source code must retain the above
8
#      copyright notice, this list of conditions and the following
9
#      disclaimer.
10
#
11
#   2. Redistributions in binary form must reproduce the above
12
#      copyright notice, this list of conditions and the following
13
#      disclaimer in the documentation and/or other materials
14
#      provided with the distribution.
15
#
16
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
20
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27
# POSSIBILITY OF SUCH DAMAGE.
28
#
29
# The views and conclusions contained in the software and
30
# documentation are those of the authors and should not be
31
# interpreted as representing official policies, either expressed
32
# or implied, of GRNET S.A.
33

    
34

    
35
def str_or_utf8(s):
36
    if isinstance(s, unicode):
37
        return s.encode('utf8')
38
    return str(s)
39

    
40

    
41
class CallError(Exception):
42
    exceptions = {}
43

    
44
    def __new__(cls, *args, **kw):
45
        call_error = kw.get('call_error', None)
46
        if call_error is None:
47
            call_error = cls.__name__
48
        else:
49
            call_error = str(call_error)
50
        cls = CallError.exceptions.get(call_error, cls)
51
        self = Exception.__new__(cls)
52
        return self
53

    
54
    def __init__(self, *args, **kw):
55
        self.call_error = kw.pop('call_error', self.__class__.__name__)
56
        self.args = args
57
        self.kwargs = kw
58

    
59
    def __str__(self):
60
        return '\n--------\n'.join(str_or_utf8(x) for x in self.args)
61

    
62
    def __repr__(self):
63
        return '%s(%s)' % (self.__class__.__name__,
64
                           ','.join(str_or_utf8(x) for x in self.args))
65

    
66
    @classmethod
67
    def from_exception(cls, exc):
68
        args = None
69
        try:
70
            args = tuple(exc.args)
71
        except (TypeError, AttributeError):
72
            pass
73

    
74
        if args is None:
75
            args = (str(exc),)
76
        self = cls(*args, call_error=exc.__class__.__name__)
77
        return self
78

    
79
    def to_dict(self):
80
        return {'call_error': self.call_error,
81
                'error_args': (self.args, self.kwargs)}
82

    
83
    @classmethod
84
    def from_dict(cls, dictobj):
85
        args = None
86
        try:
87
            if 'error_args' in dictobj and 'call_error' in dictobj:
88
                args = dictobj['error_args']
89
                call_error = dictobj['call_error']
90
        except TypeError:
91
            pass
92

    
93
        if args is None:
94
            args = (str(dictobj),)
95
            call_error = 'UnknownError'
96
            kw = {}
97
        else:
98
            args, kw = args
99

    
100
        self = cls(*args, call_error=call_error, **kw)
101
        return self
102

    
103

    
104
def register_exceptions(*exceptions):
105
    for exception in exceptions:
106
        if not issubclass(exception, CallError):
107
            m = "Registering '%s': is not a CallError subclass" % (exception,)
108
            raise ValueError(m)
109
        CallError.exceptions[exception.__name__] = exception
110

    
111

    
112
def register_exception(exc):
113
    register_exceptions(exc)
114
    return exc
115

    
116

    
117
@register_exception
118
class CorruptedError(CallError):
119
    pass
120

    
121

    
122
@register_exception
123
class InvalidDataError(CallError):
124
    pass
125

    
126

    
127
class ReturnButFail(Exception):
128
    def __init__(self, retval=None):
129
        self.data = retval