update from RIFT as of 696b75d2fe9fb046261b08c616f1bcf6c0b54a9b second try
[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 gi.require_version('RwCal', '1.0')
26
27 from gi.repository import RwTypes, RwCal
28
29 def rwcalstatus_from_exc_map(exc_map):
30 """ Creates an rwcalstatus decorator from a dictionary mapping exception
31 types to rwstatus codes, and return a error object containing Exception details
32 """
33
34 # A decorator that maps a Python exception to a particular return code.
35 # Also returns an object containing the error msg, traceback and rwstatus
36 # Automatically returns RW_SUCCESS when no Python exception was thrown.
37 # Prevents us from having to use try: except: handlers around every function call.
38
39 def rwstatus(arg=None, ret_on_failure=None):
40 def decorator(func):
41 @functools.wraps(func)
42 def wrapper(*args, **kwds):
43 rwcal_status = RwCal.RwcalStatus()
44 try:
45 ret = func(*args, **kwds)
46
47 except Exception as e:
48 rwcal_status.traceback = traceback.format_exc()
49 rwcal_status.error_msg = str(e)
50
51 ret_code = [status for exc, status in exc_map.items() if isinstance(e, exc)]
52 ret_list = [None] if ret_on_failure is None else list(ret_on_failure)
53 if len(ret_code):
54 rwcal_status.status = ret_code[0]
55 else:
56 # If it was not explicitly mapped, print the full traceback as this
57 # is not an anticipated error.
58 traceback.print_exc()
59 rwcal_status.status = RwTypes.RwStatus.FAILURE
60
61 ret_list.insert(0, rwcal_status)
62 return tuple(ret_list)
63
64
65 rwcal_status.status = RwTypes.RwStatus.SUCCESS
66 rwcal_status.traceback = ""
67 rwcal_status.error_msg = ""
68 ret_list = [rwcal_status]
69 if ret is not None:
70 if type(ret) == tuple:
71 ret_list.extend(ret)
72 else:
73 ret_list.append(ret)
74
75 return tuple(ret_list)
76
77 return wrapper
78
79 if isinstance(arg, dict):
80 exc_map.update(arg)
81 return decorator
82 elif ret_on_failure is not None:
83 return decorator
84 else:
85 return decorator(arg)
86
87 return rwstatus