Skip to content

Commit a1e674d

Browse files
committed
Support continuable and fatal exceptions.
Implemented support for new feature in RF 2.8.4 [1]. Fixes #11. [1] https://code.google.com/p/robotframework/issues/detail?id=1628 Older Remote libraries will simply ignore the new values in the result dictionary. This version always sends continuable/fatal info. Issue #12 covers sending only information that is actually needed.
1 parent f60bfb8 commit a1e674d

File tree

4 files changed

+55
-10
lines changed

4 files changed

+55
-10
lines changed

atest/libs/failing.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,21 @@ def failure_deeper(self, rounds=10):
2222
raise RuntimeError('Finally failing')
2323
self.failure_deeper(rounds-1)
2424

25+
def continuable(self, message):
26+
self._raise_special(message, continuable=True)
27+
28+
def fatal(self, message):
29+
self._raise_special(message, fatal='yes')
30+
31+
def not_special(self, message):
32+
self._raise_special(message)
33+
34+
def _raise_special(self, message, continuable=False, fatal=False):
35+
special = AssertionError(message)
36+
special.ROBOT_CONTINUE_ON_FAILURE = continuable
37+
special.ROBOT_EXIT_ON_FAILURE = fatal
38+
raise special
39+
2540

2641
class MyException(Exception):
2742
pass
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
*** Settings ***
2+
Resource resource.robot
3+
Suite Setup Start And Import Remote Library failing.py
4+
Suite Teardown Stop Remote Library
5+
6+
*** Test Cases ***
7+
Not special
8+
[Documentation] FAIL message
9+
Not special message
10+
Fail This should not be executed
11+
12+
Continuable
13+
[Documentation] FAIL Several failures occurred:\n\n
14+
... 1) message\n\n
15+
... 2) second message\n\n
16+
... 3) third message
17+
Continuable message
18+
Continuable second message
19+
Continuable third message
20+
21+
Fatal
22+
[Documentation] FAIL Execution ends here
23+
Fatal Execution ends here
24+
Fail This should not be executed
25+
26+
Fails due to earlier fatal error
27+
[Documentation] FAIL Test execution stopped due to a fatal error.
28+
Fail This should not be executed

atest/tests/basic_communication.robot

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ Passing
1313
Failing
1414
[Documentation] FAIL This is the error we get
1515
Failing This is the error we get
16+
Fail This should not be executed
1617

1718
Logging
1819
[Documentation] LOG 1 INFO Hello, world! LOG 2 WARN Warning, warning!!

src/robotremoteserver.py

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -112,12 +112,17 @@ def run_keyword(self, name, args, kwargs=None):
112112
try:
113113
return_value = self._get_keyword(name)(*args, **kwargs)
114114
except:
115-
result['error'], result['traceback'] = self._get_error_details()
115+
exc_type, exc_value, exc_tb = sys.exc_info()
116+
result['error'] = self._get_error_message(exc_type, exc_value)
117+
result['traceback'] = self._get_error_traceback(exc_tb)
118+
result['continuable'] = self._get_error_attribute(exc_value, 'CONTINUE')
119+
result['fatal'] = self._get_error_attribute(exc_value, 'EXIT')
116120
else:
117121
try:
118122
result['return'] = self._handle_return_value(return_value)
119123
except:
120-
result['error'] = self._get_error_message()
124+
exc_type, exc_value, _ = sys.exc_info()
125+
result['error'] = self._get_error_message(exc_type, exc_value)
121126
else:
122127
result['status'] = 'PASS'
123128
result['output'] = self._restore_std_streams()
@@ -165,17 +170,10 @@ def _get_keyword(self, name):
165170
return kw
166171
return None
167172

168-
def _get_error_details(self):
169-
exc_type, exc_value, exc_tb = sys.exc_info()
173+
def _get_error_message(self, exc_type, exc_value):
170174
if exc_type in self._fatal_exceptions:
171175
self._restore_std_streams()
172176
raise
173-
return (self._get_error_message(exc_type, exc_value),
174-
self._get_error_traceback(exc_tb))
175-
176-
def _get_error_message(self, exc_type=None, exc_value=None):
177-
if exc_type is None:
178-
exc_type, exc_value = sys.exc_info()[:2]
179177
name = exc_type.__name__
180178
message = self._get_message_from_exception(exc_value)
181179
if not message:
@@ -199,6 +197,9 @@ def _get_error_traceback(self, exc_tb):
199197
trace = ''.join(traceback.format_list(entries))
200198
return 'Traceback (most recent call last):\n' + trace
201199

200+
def _get_error_attribute(self, exc_value, name):
201+
return bool(getattr(exc_value, 'ROBOT_%s_ON_FAILURE' % name, False))
202+
202203
def _handle_return_value(self, ret):
203204
if isinstance(ret, basestring):
204205
return self._handle_binary_result(ret)

0 commit comments

Comments
 (0)