blob: 2978e290eb32a75f5ef844dba1851548a448b6e9 [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')
Jeremy Mordkoff4870d0e2017-09-30 20:28:33 -040025gi.require_version('RwCal', '1.0')
Jeremy Mordkoff6f07e6f2016-09-07 18:56:51 -040026
27from gi.repository import RwTypes, RwCal
28
29def 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