6867140d1c4c9c356c9e3b4512921540beafb8d7
[osm/SO.git] / rwcal / rift / cal / rwcal_status.py
1 #!/usr/bin/env python
2 #
3 # Copyright 2016 RIFT.IO Inc
4 #
5 # Licensed under the Apache License, Version 2.0 (the "License");
6 # you may not use this file except in compliance with the License.
7 # You may obtain a copy of the License at
8 #
9 # http://www.apache.org/licenses/LICENSE-2.0
10 #
11 # Unless required by applicable law or agreed to in writing, software
12 # distributed under the License is distributed on an "AS IS" BASIS,
13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 # See the License for the specific language governing permissions and
15 # limitations under the License.
16 #
17 #
18 # @file rwcal_status.py
19 # @brief This module defines Python utilities for dealing with rwcalstatus codes.
20
21 import traceback
22 import functools
23 import gi
24 gi.require_version('RwTypes', '1.0')
25
26 from gi.repository import RwTypes, RwCal
27
28 def rwcalstatus_from_exc_map(exc_map):
29 """ Creates an rwcalstatus decorator from a dictionary mapping exception
30 types to rwstatus codes, and return a error object containing Exception details
31 """
32
33 # A decorator that maps a Python exception to a particular return code.
34 # Also returns an object containing the error msg, traceback and rwstatus
35 # Automatically returns RW_SUCCESS when no Python exception was thrown.
36 # Prevents us from having to use try: except: handlers around every function call.
37
38 def rwstatus(arg=None, ret_on_failure=None):
39 def decorator(func):
40 @functools.wraps(func)
41 def wrapper(*args, **kwds):
42 rwcal_status = RwCal.RwcalStatus()
43 try:
44 ret = func(*args, **kwds)
45
46 except Exception as e:
47 rwcal_status.traceback = traceback.format_exc()
48 rwcal_status.error_msg = str(e)
49
50 ret_code = [status for exc, status in exc_map.items() if isinstance(e, exc)]
51 ret_list = [None] if ret_on_failure is None else list(ret_on_failure)
52 if len(ret_code):
53 rwcal_status.status = ret_code[0]
54 else:
55 # If it was not explicitly mapped, print the full traceback as this
56 # is not an anticipated error.
57 traceback.print_exc()
58 rwcal_status.status = RwTypes.RwStatus.FAILURE
59
60 ret_list.insert(0, rwcal_status)
61 return tuple(ret_list)
62
63
64 rwcal_status.status = RwTypes.RwStatus.SUCCESS
65 rwcal_status.traceback = ""
66 rwcal_status.error_msg = ""
67 ret_list = [rwcal_status]
68 if ret is not None:
69 if type(ret) == tuple:
70 ret_list.extend(ret)
71 else:
72 ret_list.append(ret)
73
74 return tuple(ret_list)
75
76 return wrapper
77
78 if isinstance(arg, dict):
79 exc_map.update(arg)
80 return decorator
81 elif ret_on_failure is not None:
82 return decorator
83 else:
84 return decorator(arg)
85
86 return rwstatus