Robot Framework Integrated Development Environment (RIDE)
errors.py
Go to the documentation of this file.
1 # Copyright 2008-2015 Nokia Networks
2 # Copyright 2016- Robot Framework Foundation
3 #
4 # Licensed under the Apache License, Version 2.0 (the "License");
5 # you may not use this file except in compliance with the License.
6 # You may obtain a copy of the License at
7 #
8 # http://www.apache.org/licenses/LICENSE-2.0
9 #
10 # Unless required by applicable law or agreed to in writing, software
11 # distributed under the License is distributed on an "AS IS" BASIS,
12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 # See the License for the specific language governing permissions and
14 # limitations under the License.
15 
16 
20 
21 try:
22  unicode
23 except NameError:
24  unicode = str
25 
26 
27 # Return codes from Robot and Rebot.
28 # RC below 250 is the number of failed critical tests and exactly 250
29 # means that number or more such failures.
30 INFO_PRINTED = 251 # --help or --version
31 DATA_ERROR = 252 # Invalid data or cli args
32 STOPPED_BY_USER = 253 # KeyboardInterrupt or SystemExit
33 FRAMEWORK_ERROR = 255 # Unexpected error
34 
35 
36 
41 
42  def __init__(self, message='', details=''):
43  Exception.__init__(self, message)
44  self.detailsdetails = details
45 
46  @property
47  message = property
48 
49  def message(self):
50  return unicode(self)
51 
52 
53 
60 
61 
62 
67 class DataError(RobotError):
68 
69 
70 
76 
77 
78 
83 class KeywordError(DataError):
84 
85 
86 
94 
95  def __init__(self, message='', test_timeout=True):
96  RobotError.__init__(self, message)
97  self.test_timeouttest_timeout = test_timeout
98 
99  @property
100  keyword_timeout = property
101 
102  def keyword_timeout(self):
103  return not self.test_timeouttest_timeout
104 
105 
106 
108 
109 
110 
111 class ExecutionStatus(RobotError):
112 
113  def __init__(self, message, test_timeout=False, keyword_timeout=False,
114  syntax=False, exit=False, continue_on_failure=False,
115  return_value=None):
116  if '\r\n' in message:
117  message = message.replace('\r\n', '\n')
118  from robotide.lib.robot.utils import cut_long_message
119  RobotError.__init__(self, cut_long_message(message))
120  self.test_timeouttest_timeout = test_timeout
121  self.keyword_timeoutkeyword_timeout = keyword_timeout
122  self.syntaxsyntax = syntax
123  self.exitexit = exit
124  self._continue_on_failure_continue_on_failure = continue_on_failure
125  self.return_valuereturn_value = return_value
126 
127  @property
128  timeout = property
129 
130  def timeout(self):
131  return self.test_timeouttest_timeout or self.keyword_timeoutkeyword_timeout
132 
133  @property
134  dont_continue = property
135 
136  def dont_continue(self):
137  return self.timeouttimeouttimeout or self.syntaxsyntax or self.exitexit
138 
139  @property
140  continue_on_failure = property
141 
143  return self._continue_on_failure_continue_on_failure
144 
145  @continue_on_failure.setter
146 
147  def continue_on_failure(self, continue_on_failure):
148  self._continue_on_failure_continue_on_failure = continue_on_failure
149  for child in getattr(self, '_errors', []):
150  if child is not self:
151  child.continue_on_failure = continue_on_failure
152 
153  def can_continue(self, teardown=False, templated=False, dry_run=False):
154  if dry_run:
155  return True
156  if self.syntaxsyntax or self.exitexit or self.test_timeouttest_timeout:
157  return False
158  if templated:
159  return True
160  if self.keyword_timeoutkeyword_timeout:
161  return False
162  if teardown:
163  return True
164  return self.continue_on_failurecontinue_on_failurecontinue_on_failurecontinue_on_failure
165 
166  def get_errors(self):
167  return [self]
168 
169  @property
170  status = property
171 
172  def status(self):
173  return 'FAIL'
174 
175 
176 
178 
179 
180 class HandlerExecutionFailed(ExecutionFailed):
181 
182  def __init__(self, details):
183  error = details.error
184  timeout = isinstance(error, TimeoutError)
185  test_timeout = timeout and error.test_timeout
186  keyword_timeout = timeout and error.keyword_timeout
187  syntax = (isinstance(error, DataError)
188  and not isinstance(error, (KeywordError, VariableError)))
189  exit_on_failure = self._get_get(error, 'EXIT_ON_FAILURE')
190  continue_on_failure = self._get_get(error, 'CONTINUE_ON_FAILURE')
191  ExecutionFailed.__init__(self, details.message, test_timeout,
192  keyword_timeout, syntax, exit_on_failure,
193  continue_on_failure)
194  self.full_messagefull_message = details.message
195  self.tracebacktraceback = details.traceback
196 
197  def _get(self, error, attr):
198  return bool(getattr(error, 'ROBOT_' + attr, False))
199 
200 
202 
203  def __init__(self, errors, message=None):
204  message = message or self._format_message_format_message([e.message for e in errors])
205  ExecutionFailed.__init__(self, message, **self._get_attrs_get_attrs(errors))
206  self._errors_errors = errors
207 
208  def _format_message(self, messages):
209  if len(messages) == 1:
210  return messages[0]
211  prefix = 'Several failures occurred:'
212  if any(msg.startswith('*HTML*') for msg in messages):
213  prefix = '*HTML* ' + prefix
214  messages = self._format_html_messages_format_html_messages(messages)
215  return '\n\n'.join(
216  [prefix] +
217  ['%d) %s' % (i, m) for i, m in enumerate(messages, start=1)]
218  )
219 
220  def _format_html_messages(self, messages):
221  from robotide.lib.robot.utils import html_escape
222  for msg in messages:
223  if msg.startswith('*HTML*'):
224  yield msg[6:].lstrip()
225  else:
226  yield html_escape(msg)
227 
228  def _get_attrs(self, errors):
229  return {
230  'test_timeout': any(e.test_timeout for e in errors),
231  'keyword_timeout': any(e.keyword_timeout for e in errors),
232  'syntax': any(e.syntax for e in errors),
233  'exit': any(e.exit for e in errors),
234  'continue_on_failure': all(e.continue_on_failure for e in errors)
235  }
236 
237  def get_errors(self):
238  return self._errors_errors
239 
240 
242 
243  def __init__(self, run_errors=None, teardown_errors=None):
244  errors = self._get_active_errors_get_active_errors(run_errors, teardown_errors)
245  message = self._get_message_get_message(run_errors, teardown_errors)
246  ExecutionFailures.__init__(self, errors, message)
247  if run_errors and not teardown_errors:
248  self._errors_errors_errors = run_errors.get_errors()
249  else:
250  self._errors_errors_errors = [self]
251 
252  def _get_active_errors(self, *errors):
253  return [err for err in errors if err]
254 
255  def _get_message(self, run_errors, teardown_errors):
256  run_msg = run_errors.message if run_errors else ''
257  td_msg = teardown_errors.message if teardown_errors else ''
258  if not td_msg:
259  return run_msg
260  if not run_msg:
261  return 'Keyword teardown failed:\n%s' % td_msg
262  return '%s\n\nAlso keyword teardown failed:\n%s' % (run_msg, td_msg)
263 
264 
265 
270 
271  def __init__(self, message=None, **kwargs):
272  ExecutionStatus.__init__(self, message or self._get_message_get_message(), **kwargs)
273  self._earlier_failures_earlier_failures = []
274 
275  def _get_message(self):
276  from robotide.lib.robot.utils import printable_name
277  return ("Invalid '%s' usage."
278  % printable_name(type(self).__name__, code_style=True))
279 
280  def set_earlier_failures(self, failures):
281  if failures:
282  self._earlier_failures_earlier_failures = list(failures) + self._earlier_failures_earlier_failures
283 
284  @property
285  earlier_failures = property
286 
287  def earlier_failures(self):
288  if not self._earlier_failures_earlier_failures:
289  return None
290  return ExecutionFailures(self._earlier_failures_earlier_failures)
291 
292  @property
293  status = property
294 
295  def status(self):
296  return 'PASS' if not self._earlier_failures_earlier_failures else 'FAIL'
297 
298 
299 
301 
302  def __init__(self, message):
303  ExecutionPassed.__init__(self, message)
304 
305 
306 
308 
309 
310 
311 class ExitForLoop(ExecutionPassed):
312 
313 
314 
316 
317  def __init__(self, return_value=None, failures=None):
318  ExecutionPassed.__init__(self, return_value=return_value)
319  if failures:
320  self.set_earlier_failuresset_earlier_failures(failures)
321 
322 
323 
325 
326  def __init__(self, message='', details='', fatal=False, continuable=False):
327  RobotError.__init__(self, message, details)
328  self.ROBOT_EXIT_ON_FAILUREROBOT_EXIT_ON_FAILURE = fatal
329  self.ROBOT_CONTINUE_ON_FAILUREROBOT_CONTINUE_ON_FAILURE = continuable
Used by 'Continue For Loop' keyword.
Definition: errors.py:307
Used when variable does not exist.
Definition: errors.py:67
Used for communicating failures in test execution.
Definition: errors.py:177
def _format_html_messages(self, messages)
Definition: errors.py:220
def __init__(self, errors, message=None)
Definition: errors.py:203
Base class for all exceptions communicating that execution passed.
Definition: errors.py:269
def set_earlier_failures(self, failures)
Definition: errors.py:280
def __init__(self, message=None, **kwargs)
Definition: errors.py:271
def __init__(self, message, test_timeout=False, keyword_timeout=False, syntax=False, exit=False, continue_on_failure=False, return_value=None)
Definition: errors.py:115
def continue_on_failure(self, continue_on_failure)
Definition: errors.py:147
def can_continue(self, teardown=False, templated=False, dry_run=False)
Definition: errors.py:153
Used by 'Return From Keyword' keyword.
Definition: errors.py:311
Can be used when the core framework goes to unexpected state.
Definition: errors.py:59
Used by argument parser with –help or –version.
Definition: errors.py:107
Used when a test or keyword timeout occurs.
Definition: errors.py:83
Used by 'Pass Execution' keyword.
Definition: errors.py:300
Used by Remote library to report remote errors.
Definition: errors.py:324
def __init__(self, message='', details='', fatal=False, continuable=False)
Definition: errors.py:326
def __init__(self, return_value=None, failures=None)
Definition: errors.py:317
Base class for Robot Framework errors.
Definition: errors.py:40
def __init__(self, message='', details='')
Definition: errors.py:42
def __init__(self, message='', test_timeout=True)
Definition: errors.py:95
def __init__(self, run_errors=None, teardown_errors=None)
Definition: errors.py:243
def _get_message(self, run_errors, teardown_errors)
Definition: errors.py:255
Used when no keyword is found or there is more than one match.
Definition: errors.py:75
unicode
Exceptions and return codes used internally.
Definition: errors.py:24
def html_escape(text, linkify=True)
Definition: markuputils.py:40
def printable_name(string, code_style=False)
Generates and returns printable name from the given string.
Definition: misc.py:76