blob: 6867140d1c4c9c356c9e3b4512921540beafb8d7 [file] [log] [blame]
Jeremy Mordkoff6f07e6f2016-09-07 18:56:51 -04001#!/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
21import traceback
22import functools
23import gi
24gi.require_version('RwTypes', '1.0')
25
26from gi.repository import RwTypes, RwCal
27
28def 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