blob: 076d7f48ebdd3ddd42e4d9fcbd423991430528be [file] [log] [blame]
Aviv Keshet39164ca2013-03-27 15:08:33 -07001#pylint: disable-msg=C0111
2
mbligh906b9f72007-11-29 18:56:17 +00003"""
4Internal global error types
5"""
6
Alex Miller30837902013-02-02 15:52:43 -08007import sys, traceback, threading
mbligh906b9f72007-11-29 18:56:17 +00008from traceback import format_exception
9
mbligh91672252008-10-16 22:28:34 +000010# Add names you want to be imported by 'from errors import *' to this list.
11# This must be list not a tuple as we modify it to include all of our
12# the Exception classes we define below at the end of this file.
Eric Li861b2d52011-02-04 14:50:35 -080013__all__ = ['format_error', 'context_aware', 'context', 'get_context',
14 'exception_context']
mbligh91672252008-10-16 22:28:34 +000015
16
mbligh906b9f72007-11-29 18:56:17 +000017def format_error():
jadmanski0afbb632008-06-06 21:10:57 +000018 t, o, tb = sys.exc_info()
19 trace = format_exception(t, o, tb)
20 # Clear the backtrace to prevent a circular reference
21 # in the heap -- as per tutorial
22 tb = ''
mbligh906b9f72007-11-29 18:56:17 +000023
jadmanski0afbb632008-06-06 21:10:57 +000024 return ''.join(trace)
mbligh906b9f72007-11-29 18:56:17 +000025
mbligh4f407462008-12-03 15:22:39 +000026
Eric Li861b2d52011-02-04 14:50:35 -080027# Exception context information:
28# ------------------------------
29# Every function can have some context string associated with it.
30# The context string can be changed by calling context(str) and cleared by
31# calling context() with no parameters.
32# get_context() joins the current context strings of all functions in the
33# provided traceback. The result is a brief description of what the test was
34# doing in the provided traceback (which should be the traceback of a caught
35# exception).
36#
37# For example: assume a() calls b() and b() calls c().
38#
39# @error.context_aware
40# def a():
41# error.context("hello")
42# b()
43# error.context("world")
44# error.get_context() ----> 'world'
45#
46# @error.context_aware
47# def b():
48# error.context("foo")
49# c()
50#
51# @error.context_aware
52# def c():
53# error.context("bar")
54# error.get_context() ----> 'hello --> foo --> bar'
55#
56# The current context is automatically inserted into exceptions raised in
57# context_aware functions, so usually test code doesn't need to call
58# error.get_context().
59
60ctx = threading.local()
61
62
63def _new_context(s=""):
64 if not hasattr(ctx, "contexts"):
65 ctx.contexts = []
66 ctx.contexts.append(s)
67
68
69def _pop_context():
70 ctx.contexts.pop()
71
72
73def context(s="", log=None):
74 """
75 Set the context for the currently executing function and optionally log it.
76
77 @param s: A string. If not provided, the context for the current function
78 will be cleared.
79 @param log: A logging function to pass the context message to. If None, no
80 function will be called.
81 """
82 ctx.contexts[-1] = s
83 if s and log:
84 log("Context: %s" % get_context())
85
86
87def base_context(s="", log=None):
88 """
89 Set the base context for the currently executing function and optionally
90 log it. The base context is just another context level that is hidden by
91 default. Functions that require a single context level should not use
92 base_context().
93
94 @param s: A string. If not provided, the base context for the current
95 function will be cleared.
96 @param log: A logging function to pass the context message to. If None, no
97 function will be called.
98 """
99 ctx.contexts[-1] = ""
100 ctx.contexts[-2] = s
101 if s and log:
102 log("Context: %s" % get_context())
103
104
105def get_context():
106 """Return the current context (or None if none is defined)."""
107 if hasattr(ctx, "contexts"):
108 return " --> ".join([s for s in ctx.contexts if s])
109
110
111def exception_context(e):
112 """Return the context of a given exception (or None if none is defined)."""
113 if hasattr(e, "_context"):
Alex Miller30837902013-02-02 15:52:43 -0800114 return e._context # pylint: disable=W0212
Eric Li861b2d52011-02-04 14:50:35 -0800115
116
117def set_exception_context(e, s):
118 """Set the context of a given exception."""
119 e._context = s
120
121
122def join_contexts(s1, s2):
123 """Join two context strings."""
124 if s1:
125 if s2:
126 return "%s --> %s" % (s1, s2)
127 else:
128 return s1
129 else:
130 return s2
131
132
133def context_aware(fn):
134 """A decorator that must be applied to functions that call context()."""
135 def new_fn(*args, **kwargs):
136 _new_context()
137 _new_context("(%s)" % fn.__name__)
138 try:
139 try:
140 return fn(*args, **kwargs)
141 except Exception, e:
142 if not exception_context(e):
143 set_exception_context(e, get_context())
144 raise
145 finally:
146 _pop_context()
147 _pop_context()
148 new_fn.__name__ = fn.__name__
149 new_fn.__doc__ = fn.__doc__
150 new_fn.__dict__.update(fn.__dict__)
151 return new_fn
152
153
154def _context_message(e):
155 s = exception_context(e)
156 if s:
157 return " [context: %s]" % s
158 else:
159 return ""
160
161
beeps60aec242013-06-26 14:47:48 -0700162
163class TimeoutException(Exception):
164 """
165 Generic exception raised on retry timeouts.
166 """
167 pass
168
169
mbligh906b9f72007-11-29 18:56:17 +0000170class JobContinue(SystemExit):
jadmanski0afbb632008-06-06 21:10:57 +0000171 """Allow us to bail out requesting continuance."""
172 pass
mbligh906b9f72007-11-29 18:56:17 +0000173
mbligh7e1b1502008-06-06 15:05:41 +0000174
mbligh906b9f72007-11-29 18:56:17 +0000175class JobComplete(SystemExit):
jadmanski0afbb632008-06-06 21:10:57 +0000176 """Allow us to bail out indicating continuation not required."""
177 pass
mbligh906b9f72007-11-29 18:56:17 +0000178
mbligh7e1b1502008-06-06 15:05:41 +0000179
mbligh906b9f72007-11-29 18:56:17 +0000180class AutotestError(Exception):
jadmanski0afbb632008-06-06 21:10:57 +0000181 """The parent of all errors deliberatly thrown within the client code."""
Eric Li861b2d52011-02-04 14:50:35 -0800182 def __str__(self):
183 return Exception.__str__(self) + _context_message(self)
mbligh906b9f72007-11-29 18:56:17 +0000184
mbligh7e1b1502008-06-06 15:05:41 +0000185
mbligh906b9f72007-11-29 18:56:17 +0000186class JobError(AutotestError):
mbligh4f407462008-12-03 15:22:39 +0000187 """Indicates an error which terminates and fails the whole job (ABORT)."""
jadmanski0afbb632008-06-06 21:10:57 +0000188 pass
mbligh906b9f72007-11-29 18:56:17 +0000189
mbligh7e1b1502008-06-06 15:05:41 +0000190
mbligh4f407462008-12-03 15:22:39 +0000191class UnhandledJobError(JobError):
192 """Indicates an unhandled error in a job."""
193 def __init__(self, unhandled_exception):
194 if isinstance(unhandled_exception, JobError):
mbligh1ca1c2c2008-12-09 23:38:25 +0000195 JobError.__init__(self, *unhandled_exception.args)
Eric Li861b2d52011-02-04 14:50:35 -0800196 elif isinstance(unhandled_exception, str):
197 JobError.__init__(self, unhandled_exception)
mbligh4f407462008-12-03 15:22:39 +0000198 else:
199 msg = "Unhandled %s: %s"
200 msg %= (unhandled_exception.__class__.__name__,
201 unhandled_exception)
Eric Li861b2d52011-02-04 14:50:35 -0800202 if not isinstance(unhandled_exception, AutotestError):
203 msg += _context_message(unhandled_exception)
mbligh4f407462008-12-03 15:22:39 +0000204 msg += "\n" + traceback.format_exc()
205 JobError.__init__(self, msg)
206
207
mblighc2180832008-07-25 03:26:12 +0000208class TestBaseException(AutotestError):
209 """The parent of all test exceptions."""
mbligh021679f2008-11-27 00:43:19 +0000210 # Children are required to override this. Never instantiate directly.
Alex Miller30837902013-02-02 15:52:43 -0800211 exit_status = "NEVER_RAISE_THIS"
mblighc2180832008-07-25 03:26:12 +0000212
213
214class TestError(TestBaseException):
mblighb48fa562008-06-23 17:29:40 +0000215 """Indicates that something went wrong with the test harness itself."""
Alex Miller30837902013-02-02 15:52:43 -0800216 exit_status = "ERROR"
mblighb48fa562008-06-23 17:29:40 +0000217
jadmanski8d01bfe2008-06-23 18:13:24 +0000218
mblighc2180832008-07-25 03:26:12 +0000219class TestNAError(TestBaseException):
jadmanski0afbb632008-06-06 21:10:57 +0000220 """Indictates that the test is Not Applicable. Should be thrown
mblighb48fa562008-06-23 17:29:40 +0000221 when various conditions are such that the test is inappropriate."""
Alex Miller30837902013-02-02 15:52:43 -0800222 exit_status = "TEST_NA"
mblighb48fa562008-06-23 17:29:40 +0000223
jadmanski8d01bfe2008-06-23 18:13:24 +0000224
mblighc2180832008-07-25 03:26:12 +0000225class TestFail(TestBaseException):
mblighb48fa562008-06-23 17:29:40 +0000226 """Indicates that the test failed, but the job will not continue."""
Alex Miller30837902013-02-02 15:52:43 -0800227 exit_status = "FAIL"
mblighb48fa562008-06-23 17:29:40 +0000228
jadmanski8d01bfe2008-06-23 18:13:24 +0000229
mblighc2180832008-07-25 03:26:12 +0000230class TestWarn(TestBaseException):
mblighb48fa562008-06-23 17:29:40 +0000231 """Indicates that bad things (may) have happened, but not an explicit
232 failure."""
Alex Miller30837902013-02-02 15:52:43 -0800233 exit_status = "WARN"
mbligh6a2a2df2008-01-16 17:41:55 +0000234
mbligh7e1b1502008-06-06 15:05:41 +0000235
Aviv Keshet39164ca2013-03-27 15:08:33 -0700236class TestFailRetry(TestFail):
237 """Indicates that the test failed, but in a manner that may be retried
238 if test retries are enabled for this test."""
239 exit_status = "FAIL"
240
241
mblighc2180832008-07-25 03:26:12 +0000242class UnhandledTestError(TestError):
243 """Indicates an unhandled error in a test."""
244 def __init__(self, unhandled_exception):
245 if isinstance(unhandled_exception, TestError):
246 TestError.__init__(self, *unhandled_exception.args)
Eric Li861b2d52011-02-04 14:50:35 -0800247 elif isinstance(unhandled_exception, str):
248 TestError.__init__(self, unhandled_exception)
mblighc2180832008-07-25 03:26:12 +0000249 else:
250 msg = "Unhandled %s: %s"
251 msg %= (unhandled_exception.__class__.__name__,
252 unhandled_exception)
Eric Li861b2d52011-02-04 14:50:35 -0800253 if not isinstance(unhandled_exception, AutotestError):
254 msg += _context_message(unhandled_exception)
mblighc2180832008-07-25 03:26:12 +0000255 msg += "\n" + traceback.format_exc()
256 TestError.__init__(self, msg)
257
258
259class UnhandledTestFail(TestFail):
260 """Indicates an unhandled fail in a test."""
261 def __init__(self, unhandled_exception):
262 if isinstance(unhandled_exception, TestFail):
263 TestFail.__init__(self, *unhandled_exception.args)
Eric Li861b2d52011-02-04 14:50:35 -0800264 elif isinstance(unhandled_exception, str):
265 TestFail.__init__(self, unhandled_exception)
mblighc2180832008-07-25 03:26:12 +0000266 else:
267 msg = "Unhandled %s: %s"
268 msg %= (unhandled_exception.__class__.__name__,
269 unhandled_exception)
Eric Li861b2d52011-02-04 14:50:35 -0800270 if not isinstance(unhandled_exception, AutotestError):
271 msg += _context_message(unhandled_exception)
mblighc2180832008-07-25 03:26:12 +0000272 msg += "\n" + traceback.format_exc()
273 TestFail.__init__(self, msg)
274
275
mbligh906b9f72007-11-29 18:56:17 +0000276class CmdError(TestError):
Christopher Wileycd69dc02013-09-09 13:48:58 -0700277 """Indicates that a command failed, is fatal to the test unless caught."""
jadmanski0afbb632008-06-06 21:10:57 +0000278 def __init__(self, command, result_obj, additional_text=None):
279 TestError.__init__(self, command, result_obj, additional_text)
mblighc23051c2008-06-27 19:26:46 +0000280 self.command = command
281 self.result_obj = result_obj
282 self.additional_text = additional_text
mbligh6a2a2df2008-01-16 17:41:55 +0000283
jadmanski0afbb632008-06-06 21:10:57 +0000284 def __str__(self):
jadmanski6ef0b672008-09-30 22:50:19 +0000285 if self.result_obj.exit_status is None:
286 msg = "Command <%s> failed and is not responding to signals"
287 msg %= self.command
288 else:
289 msg = "Command <%s> failed, rc=%d"
290 msg %= (self.command, self.result_obj.exit_status)
291
mblighc23051c2008-06-27 19:26:46 +0000292 if self.additional_text:
293 msg += ", " + self.additional_text
Eric Li861b2d52011-02-04 14:50:35 -0800294 msg += _context_message(self)
showard6d7e94f2008-08-20 20:53:34 +0000295 msg += '\n' + repr(self.result_obj)
jadmanski0afbb632008-06-06 21:10:57 +0000296 return msg
mbligh906b9f72007-11-29 18:56:17 +0000297
mbligh7e1b1502008-06-06 15:05:41 +0000298
Christopher Wileycd69dc02013-09-09 13:48:58 -0700299class CmdTimeoutError(CmdError):
300 """Indicates that a command timed out."""
301 pass
302
303
mbligh906b9f72007-11-29 18:56:17 +0000304class PackageError(TestError):
jadmanski0afbb632008-06-06 21:10:57 +0000305 """Indicates an error trying to perform a package operation."""
306 pass
mbligh906b9f72007-11-29 18:56:17 +0000307
mbligh7e1b1502008-06-06 15:05:41 +0000308
mblighe8673102008-07-16 14:09:03 +0000309class BarrierError(JobError):
310 """Indicates an error happened during a barrier operation."""
311 pass
312
313
mbligh999fb132010-04-23 17:22:03 +0000314class BarrierAbortError(BarrierError):
315 """Indicate that the barrier was explicitly aborted by a member."""
316 pass
317
318
mbligh5deff3d2008-01-04 21:21:28 +0000319class InstallError(JobError):
jadmanski0afbb632008-06-06 21:10:57 +0000320 """Indicates an installation error which Terminates and fails the job."""
321 pass
mbligh03f4fc72007-11-29 20:56:14 +0000322
mbligh7e1b1502008-06-06 15:05:41 +0000323
mbligh6f015c42008-02-12 20:55:03 +0000324class AutotestRunError(AutotestError):
mbligh021679f2008-11-27 00:43:19 +0000325 """Indicates a problem running server side control files."""
jadmanski0afbb632008-06-06 21:10:57 +0000326 pass
mbligh6f015c42008-02-12 20:55:03 +0000327
mbligh7e1b1502008-06-06 15:05:41 +0000328
mbligh6f015c42008-02-12 20:55:03 +0000329class AutotestTimeoutError(AutotestError):
jadmanski0afbb632008-06-06 21:10:57 +0000330 """This exception is raised when an autotest test exceeds the timeout
331 parameter passed to run_timed_test and is killed.
332 """
Dale Curtis8adf7892011-09-08 16:13:36 -0700333 pass
mbligh6f015c42008-02-12 20:55:03 +0000334
335
mblighce955fc2009-08-24 21:59:02 +0000336class HostRunErrorMixIn(Exception):
337 """
338 Indicates a problem in the host run() function raised from client code.
339 Should always be constructed with a tuple of two args (error description
340 (str), run result object). This is a common class mixed in to create the
341 client and server side versions of it.
342 """
343 def __init__(self, description, result_obj):
344 self.description = description
345 self.result_obj = result_obj
346 Exception.__init__(self, description, result_obj)
347
348 def __str__(self):
349 return self.description + '\n' + repr(self.result_obj)
350
351
Dale Curtis8adf7892011-09-08 16:13:36 -0700352class HostInstallTimeoutError(JobError):
353 """
354 Indicates the machine failed to be installed after the predetermined
355 timeout.
356 """
357 pass
358
359
mblighce955fc2009-08-24 21:59:02 +0000360class AutotestHostRunError(HostRunErrorMixIn, AutotestError):
361 pass
362
363
mbligh03f4fc72007-11-29 20:56:14 +0000364# server-specific errors
365
366class AutoservError(Exception):
jadmanski0afbb632008-06-06 21:10:57 +0000367 pass
mbligh03f4fc72007-11-29 20:56:14 +0000368
369
mbligh34faa282008-01-16 17:44:49 +0000370class AutoservSSHTimeout(AutoservError):
jadmanski0afbb632008-06-06 21:10:57 +0000371 """SSH experienced a connection timeout"""
372 pass
mbligh34faa282008-01-16 17:44:49 +0000373
374
mblighce955fc2009-08-24 21:59:02 +0000375class AutoservRunError(HostRunErrorMixIn, AutoservError):
376 pass
showard6d7e94f2008-08-20 20:53:34 +0000377
mbligh03f4fc72007-11-29 20:56:14 +0000378
mbligh9d738d62009-03-09 21:17:10 +0000379class AutoservSshPermissionDeniedError(AutoservRunError):
380 """Indicates that a SSH permission denied error was encountered."""
381 pass
382
383
mbligh03f4fc72007-11-29 20:56:14 +0000384class AutoservVirtError(AutoservError):
jadmanski0afbb632008-06-06 21:10:57 +0000385 """Vitualization related error"""
386 pass
mbligh03f4fc72007-11-29 20:56:14 +0000387
388
389class AutoservUnsupportedError(AutoservError):
jadmanski0afbb632008-06-06 21:10:57 +0000390 """Error raised when you try to use an unsupported optional feature"""
391 pass
mbligh03f4fc72007-11-29 20:56:14 +0000392
mbligh7e1b1502008-06-06 15:05:41 +0000393
mbligh03f4fc72007-11-29 20:56:14 +0000394class AutoservHostError(AutoservError):
jadmanski0afbb632008-06-06 21:10:57 +0000395 """Error reaching a host"""
396 pass
mbligh03f4fc72007-11-29 20:56:14 +0000397
mbligh7e1b1502008-06-06 15:05:41 +0000398
mblighc971c5f2009-06-08 16:48:54 +0000399class AutoservHostIsShuttingDownError(AutoservHostError):
400 """Host is shutting down"""
401 pass
402
403
404class AutoservNotMountedHostError(AutoservHostError):
405 """Found unmounted partitions that should be mounted"""
406 pass
407
408
409class AutoservSshPingHostError(AutoservHostError):
410 """SSH ping failed"""
411 pass
412
413
414class AutoservDiskFullHostError(AutoservHostError):
415 """Not enough free disk space on host"""
416 def __init__(self, path, want_gb, free_space_gb):
417 AutoservHostError.__init__(self,
418 'Not enough free space on %s - %.3fGB free, want %.3fGB' %
419 (path, free_space_gb, want_gb))
420
421 self.path = path
422 self.want_gb = want_gb
423 self.free_space_gb = free_space_gb
424
425
426class AutoservHardwareHostError(AutoservHostError):
427 """Found hardware problems with the host"""
428 pass
429
430
mbligh03f4fc72007-11-29 20:56:14 +0000431class AutoservRebootError(AutoservError):
jadmanski0afbb632008-06-06 21:10:57 +0000432 """Error occured while rebooting a machine"""
433 pass
mbligh6e2ffec2008-03-05 16:08:34 +0000434
mbligh7e1b1502008-06-06 15:05:41 +0000435
jadmanski65eb8f52009-07-24 18:34:43 +0000436class AutoservShutdownError(AutoservRebootError):
437 """Error occured during shutdown of machine"""
438 pass
439
440
mbligh6e2ffec2008-03-05 16:08:34 +0000441class AutoservSubcommandError(AutoservError):
jadmanski0afbb632008-06-06 21:10:57 +0000442 """Indicates an error while executing a (forked) subcommand"""
443 def __init__(self, func, exit_code):
444 AutoservError.__init__(self, func, exit_code)
445 self.func = func
446 self.exit_code = exit_code
mbligh7e1b1502008-06-06 15:05:41 +0000447
jadmanski0afbb632008-06-06 21:10:57 +0000448 def __str__(self):
449 return ("Subcommand %s failed with exit code %d" %
450 (self.func, self.exit_code))
mbligh91672252008-10-16 22:28:34 +0000451
452
Scott Zawalski62bacae2013-03-05 10:40:32 -0500453class AutoservRepairTotalFailure(AutoservError):
454 """Raised if all attempts to repair the DUT failed."""
455 pass
456
457
458class AutoservRepairFailure(AutoservError):
459 """Raised by a repair method if it is unable to repair a DUT."""
460 pass
461
462
463class AutoservRepairMethodNA(AutoservError):
464 """Raised when for any reason a praticular repair method is NA."""
465 pass
466
467
mbligh25c0b8c2009-01-24 01:44:17 +0000468class AutoservHardwareRepairRequestedError(AutoservError):
469 """
470 Exception class raised from Host.repair_full() (or overrides) when software
471 repair fails but it successfully managed to request a hardware repair (by
472 notifying the staff, sending mail, etc)
473 """
474 pass
475
476
jadmanski2615f4a2010-07-19 16:39:56 +0000477class AutoservHardwareRepairRequiredError(AutoservError):
478 """
479 Exception class raised during repairs to indicate that a hardware repair
480 is going to be necessary.
481 """
482 pass
483
484
jadmanskic1dda212009-11-18 19:22:00 +0000485class AutoservInstallError(AutoservError):
486 """Error occured while installing autotest on a host"""
487 pass
488
489
Simran Basi31cf2bd2012-08-14 16:51:54 -0700490class AutoservPidAlreadyDeadError(AutoservError):
491 """Error occured by trying to kill a nonexistant PID"""
492 pass
493
494
jadmanskic27c2312009-08-05 20:58:51 +0000495# packaging system errors
496
497class PackagingError(AutotestError):
498 'Abstract error class for all packaging related errors.'
499
500
501class PackageUploadError(PackagingError):
502 'Raised when there is an error uploading the package'
503
504
505class PackageFetchError(PackagingError):
506 'Raised when there is an error fetching the package'
507
508
509class PackageRemoveError(PackagingError):
510 'Raised when there is an error removing the package'
511
512
513class PackageInstallError(PackagingError):
514 'Raised when there is an error installing the package'
515
516
517class RepoDiskFullError(PackagingError):
518 'Raised when the destination for packages is full'
519
520
521class RepoWriteError(PackagingError):
522 "Raised when packager cannot write to a repo's desitnation"
523
524
525class RepoUnknownError(PackagingError):
526 "Raised when packager cannot write to a repo's desitnation"
527
528
529class RepoError(PackagingError):
530 "Raised when a repo isn't working in some way"
531
532
Chris Masonef8b53062012-05-08 22:14:18 -0700533class CrosDynamicSuiteException(Exception):
534 """
Chris Masoneb4935552012-08-14 12:05:54 -0700535 Base class for exceptions coming from dynamic suite code in
536 server/cros/dynamic_suite/*.
Chris Masonef8b53062012-05-08 22:14:18 -0700537 """
538 pass
539
540
541class StageBuildFailure(CrosDynamicSuiteException):
542 """Raised when the dev server throws 500 while staging a build."""
543 pass
544
545
546class ControlFileEmpty(CrosDynamicSuiteException):
547 """Raised when the control file exists on the server, but can't be read."""
548 pass
549
550
Alex Millera713e252013-03-01 10:45:44 -0800551class ControlFileMalformed(CrosDynamicSuiteException):
552 """Raised when an invalid control file is read."""
553 pass
554
555
Chris Masonef8b53062012-05-08 22:14:18 -0700556class AsynchronousBuildFailure(CrosDynamicSuiteException):
557 """Raised when the dev server throws 500 while finishing staging of a build.
558 """
559 pass
560
561
562class SuiteArgumentException(CrosDynamicSuiteException):
563 """Raised when improper arguments are used to run a suite."""
564 pass
565
566
Chris Masone8906ab12012-07-23 15:37:56 -0700567class MalformedDependenciesException(CrosDynamicSuiteException):
568 """Raised when a build has a malformed dependency_info file."""
569 pass
570
571
Chris Masonef8b53062012-05-08 22:14:18 -0700572class InadequateHostsException(CrosDynamicSuiteException):
573 """Raised when there are too few hosts to run a suite."""
574 pass
575
576
577class NoHostsException(CrosDynamicSuiteException):
578 """Raised when there are no healthy hosts to run a suite."""
579 pass
580
581
582class ControlFileNotFound(CrosDynamicSuiteException):
583 """Raised when a control file cannot be found and/or read."""
584 pass
585
586
587class NoControlFileList(CrosDynamicSuiteException):
Chris Masone9807bd62012-07-11 14:44:17 -0700588 """Raised to indicate that a listing can't be done."""
589 pass
590
591
592class HostLockManagerReuse(CrosDynamicSuiteException):
593 """Raised when a caller tries to re-use a HostLockManager instance."""
Chris Masonef8b53062012-05-08 22:14:18 -0700594 pass
595
596
Simran Basi94d9bd02012-11-12 15:13:59 -0800597class ReimageAbortedException(CrosDynamicSuiteException):
598 """Raised when a Reimage job is aborted"""
599 pass
600
601
Alex Miller30837902013-02-02 15:52:43 -0800602class UnknownReimageType(CrosDynamicSuiteException):
603 """Raised when a suite passes in an invalid reimage type"""
604 pass
605
606
Simran Basi22aa9fe2012-12-07 16:37:09 -0800607class LabIsDownException(Exception):
608 """Raised when the Lab is Down"""
609 pass
610
611
Simran Basi41bfae42013-01-09 10:50:47 -0800612class BoardIsDisabledException(Exception):
613 """Raised when a certain board is disabled in the Lab"""
614 pass
615
616
Alex Miller24c27c12012-08-09 10:24:24 -0700617class NoUniquePackageFound(Exception):
618 """Raised when an executable cannot be mapped back to a single package."""
619 pass
620
621
Alex Miller4a193692013-08-21 13:59:01 -0700622class RPCException(Exception):
623 """Raised when an RPC encounters an error that a client might wish to
624 handle specially."""
625 pass
626
627
628class NoEligibleHostException(RPCException):
629 """Raised when no host could satisfy the requirements of a job."""
630 pass
631
632
Aviv Keshet46250752013-08-27 15:52:06 -0700633class InvalidBgJobCall(Exception):
634 """Raised when an invalid call is made to a BgJob object."""
635 pass
636
637
mbligh91672252008-10-16 22:28:34 +0000638# This MUST remain at the end of the file.
639# Limit 'from error import *' to only import the exception instances.
640for _name, _thing in locals().items():
641 try:
642 if issubclass(_thing, Exception):
643 __all__.append(_name)
644 except TypeError:
645 pass # _thing not a class
646__all__ = tuple(__all__)