1 #pylint: disable-msg=C0111 2 3 """ 4 Internal global error types 5 """ 6 7 import sys, traceback 8 from traceback import format_exception 9 10 # 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. 13 __all__ = ['format_error'] 14 15 16 def format_error(): 17 t, o, tb = sys.exc_info() 18 trace = format_exception(t, o, tb) 19 # Clear the backtrace to prevent a circular reference 20 # in the heap -- as per tutorial 21 tb = '' 22 23 return ''.join(trace) 24 25 26 class TimeoutException(Exception): 27 """Generic exception raised on retry timeouts.""" 28 29 30 class JobContinue(SystemExit): 31 """Allow us to bail out requesting continuance.""" 32 33 34 class JobComplete(SystemExit): 35 """Allow us to bail out indicating continuation not required.""" 36 37 38 class AutotestError(Exception): 39 """The parent of all errors deliberatly thrown within the client code.""" 40 41 42 class JobError(AutotestError): 43 """Indicates an error which terminates and fails the whole job (ABORT).""" 44 45 46 class UnhandledJobError(JobError): 47 """Indicates an unhandled error in a job.""" 48 def __init__(self, unhandled_exception): 49 if isinstance(unhandled_exception, JobError): 50 JobError.__init__(self, *unhandled_exception.args) 51 elif isinstance(unhandled_exception, basestring): 52 JobError.__init__(self, unhandled_exception) 53 else: 54 msg = "Unhandled %s: %s" 55 msg %= (unhandled_exception.__class__.__name__, 56 unhandled_exception) 57 msg += "\n" + traceback.format_exc() 58 JobError.__init__(self, msg) 59 60 61 class TestBaseException(AutotestError): 62 """The parent of all test exceptions.""" 63 # Children are required to override this. Never instantiate directly. 64 exit_status = "NEVER_RAISE_THIS" 65 66 67 class TestError(TestBaseException): 68 """Indicates that something went wrong with the test harness itself.""" 69 exit_status = "ERROR" 70 71 72 class TestNAError(TestBaseException): 73 """Indictates that the test is Not Applicable. Should be thrown 74 when various conditions are such that the test is inappropriate.""" 75 exit_status = "TEST_NA" 76 77 78 class TestFail(TestBaseException): 79 """Indicates that the test failed, but the job will not continue.""" 80 exit_status = "FAIL" 81 82 83 class TestWarn(TestBaseException): 84 """Indicates that bad things (may) have happened, but not an explicit 85 failure.""" 86 exit_status = "WARN" 87 88 89 class TestFailRetry(TestFail): 90 """Indicates that the test failed, but in a manner that may be retried 91 if test retries are enabled for this test.""" 92 exit_status = "FAIL" 93 94 95 class UnhandledTestError(TestError): 96 """Indicates an unhandled error in a test.""" 97 def __init__(self, unhandled_exception): 98 if isinstance(unhandled_exception, TestError): 99 TestError.__init__(self, *unhandled_exception.args) 100 elif isinstance(unhandled_exception, basestring): 101 TestError.__init__(self, unhandled_exception) 102 else: 103 msg = "Unhandled %s: %s" 104 msg %= (unhandled_exception.__class__.__name__, 105 unhandled_exception) 106 msg += "\n" + traceback.format_exc() 107 TestError.__init__(self, msg) 108 109 110 class UnhandledTestFail(TestFail): 111 """Indicates an unhandled fail in a test.""" 112 def __init__(self, unhandled_exception): 113 if isinstance(unhandled_exception, TestFail): 114 TestFail.__init__(self, *unhandled_exception.args) 115 elif isinstance(unhandled_exception, basestring): 116 TestFail.__init__(self, unhandled_exception) 117 else: 118 msg = "Unhandled %s: %s" 119 msg %= (unhandled_exception.__class__.__name__, 120 unhandled_exception) 121 msg += "\n" + traceback.format_exc() 122 TestFail.__init__(self, msg) 123 124 125 class CmdError(TestError): 126 """Indicates that a command failed, is fatal to the test unless caught.""" 127 def __init__(self, command, result_obj, additional_text=None): 128 TestError.__init__(self, command, result_obj, additional_text) 129 self.command = command 130 self.result_obj = result_obj 131 self.additional_text = additional_text 132 133 def __str__(self): 134 if self.result_obj.exit_status is None: 135 msg = "Command <%s> failed and is not responding to signals" 136 msg %= self.command 137 else: 138 msg = "Command <%s> failed, rc=%d" 139 msg %= (self.command, self.result_obj.exit_status) 140 141 if self.additional_text: 142 msg += ", " + self.additional_text 143 msg += '\n' + repr(self.result_obj) 144 return msg 145 146 def __eq__(self, other): 147 if type(self) == type(other): 148 return (self.command == other.command 149 and self.result_obj == other.result_obj 150 and self.additional_text == other.additional_text) 151 else: 152 return NotImplemented 153 154 155 class CmdTimeoutError(CmdError): 156 """Indicates that a command timed out.""" 157 158 159 class PackageError(TestError): 160 """Indicates an error trying to perform a package operation.""" 161 162 163 class BarrierError(JobError): 164 """Indicates an error happened during a barrier operation.""" 165 166 167 class BarrierAbortError(BarrierError): 168 """Indicate that the barrier was explicitly aborted by a member.""" 169 170 171 class InstallError(JobError): 172 """Indicates an installation error which Terminates and fails the job.""" 173 174 175 class AutotestRunError(AutotestError): 176 """Indicates a problem running server side control files.""" 177 178 179 class AutotestTimeoutError(AutotestError): 180 """This exception is raised when an autotest test exceeds the timeout 181 parameter passed to run_timed_test and is killed. 182 """ 183 184 185 class GenericHostRunError(Exception): 186 """Indicates a problem in the host run() function running in either client 187 or server code. 188 189 Should always be constructed with a tuple of two args (error description 190 (str), run result object). This is a common class used to create the client 191 and server side versions of it when the distinction is useful. 192 """ 193 def __init__(self, description, result_obj): 194 self.description = description 195 self.result_obj = result_obj 196 Exception.__init__(self, description, result_obj) 197 198 def __str__(self): 199 return self.description + '\n' + repr(self.result_obj) 200 201 202 class HostInstallTimeoutError(JobError): 203 """ 204 Indicates the machine failed to be installed after the predetermined 205 timeout. 206 """ 207 208 209 class AutotestHostRunError(GenericHostRunError, AutotestError): 210 pass 211 212 213 class AutotestHostRunCmdError(AutotestHostRunError): 214 """Indicates that the command run via Host.run failed. 215 216 This is equivalent to CmdError when raised from a Host object instead of 217 directly on the DUT using utils.run 218 """ 219 220 def __init__(self, command, result_obj, additional_text=''): 221 description = command 222 if additional_text: 223 description += ' (%s)' % additional_text 224 super(AutotestHostRunCmdError, self).__init__(description, result_obj) 225 self.command = command 226 self.additional_text = additional_text 227 228 229 class AutotestHostRunTimeoutError(AutotestHostRunCmdError): 230 """Indicates that a command run via Host.run timed out. 231 232 This is equivalent to CmdTimeoutError when raised from a Host object instead 233 of directly on the DUT using utils.run 234 """ 235 236 237 # server-specific errors 238 239 class AutoservError(Exception): 240 pass 241 242 243 class AutoservSSHTimeout(AutoservError): 244 """SSH experienced a connection timeout""" 245 246 247 class AutoservRunError(GenericHostRunError, AutoservError): 248 pass 249 250 251 class AutoservSshPermissionDeniedError(AutoservRunError): 252 """Indicates that a SSH permission denied error was encountered.""" 253 254 255 class AutoservUnsupportedError(AutoservError): 256 """Error raised when you try to use an unsupported optional feature""" 257 258 259 class AutoservHostError(AutoservError): 260 """Error reaching a host""" 261 262 263 class AutoservHostIsShuttingDownError(AutoservHostError): 264 """Host is shutting down""" 265 266 267 class AutoservNotMountedHostError(AutoservHostError): 268 """Found unmounted partitions that should be mounted""" 269 270 271 class AutoservSshPingHostError(AutoservHostError): 272 """SSH ping failed""" 273 274 275 class AutoservDiskFullHostError(AutoservHostError): 276 """Not enough free disk space on host""" 277 278 def __init__(self, path, want_gb, free_space_gb): 279 super(AutoservDiskFullHostError, self).__init__( 280 'Not enough free space on %s - %.3fGB free, want %.3fGB' % 281 (path, free_space_gb, want_gb)) 282 self.path = path 283 self.want_gb = want_gb 284 self.free_space_gb = free_space_gb 285 286 287 class AutoservNoFreeInodesError(AutoservHostError): 288 """Not enough free i-nodes on host""" 289 290 def __init__(self, path, want_inodes, free_inodes): 291 super(AutoservNoFreeInodesError, self).__init__( 292 'Not enough free inodes on %s - %d free, want %d' % 293 (path, free_inodes, want_inodes)) 294 self.path = path 295 self.want_inodes = want_inodes 296 self.free_inodes = free_inodes 297 298 299 class AutoservHardwareHostError(AutoservHostError): 300 """Found hardware problems with the host""" 301 302 303 class AutoservRebootError(AutoservError): 304 """Error occured while rebooting a machine""" 305 306 307 class AutoservShutdownError(AutoservRebootError): 308 """Error occured during shutdown of machine""" 309 310 311 class AutoservSuspendError(AutoservRebootError): 312 """Error occured while suspending a machine""" 313 314 315 class AutoservSubcommandError(AutoservError): 316 """Indicates an error while executing a (forked) subcommand""" 317 def __init__(self, func, exit_code): 318 AutoservError.__init__(self, func, exit_code) 319 self.func = func 320 self.exit_code = exit_code 321 322 def __str__(self): 323 return ("Subcommand %s failed with exit code %d" % 324 (self.func, self.exit_code)) 325 326 327 class AutoservRepairTotalFailure(AutoservError): 328 """Raised if all attempts to repair the DUT failed.""" 329 330 331 class AutoservInstallError(AutoservError): 332 """Error occured while installing autotest on a host""" 333 334 335 class AutoservPidAlreadyDeadError(AutoservError): 336 """Error occured by trying to kill a nonexistant PID""" 337 338 339 # packaging system errors 340 341 class PackagingError(AutotestError): 342 'Abstract error class for all packaging related errors.' 343 344 345 class PackageUploadError(PackagingError): 346 'Raised when there is an error uploading the package' 347 348 349 class PackageFetchError(PackagingError): 350 'Raised when there is an error fetching the package' 351 352 353 class PackageRemoveError(PackagingError): 354 'Raised when there is an error removing the package' 355 356 357 class PackageInstallError(PackagingError): 358 'Raised when there is an error installing the package' 359 360 361 class RepoDiskFullError(PackagingError): 362 'Raised when the destination for packages is full' 363 364 365 class RepoWriteError(PackagingError): 366 "Raised when packager cannot write to a repo's desitnation" 367 368 369 class RepoUnknownError(PackagingError): 370 "Raised when packager cannot write to a repo's desitnation" 371 372 373 class RepoError(PackagingError): 374 "Raised when a repo isn't working in some way" 375 376 377 class StageControlFileFailure(Exception): 378 """Exceptions encountered staging control files.""" 379 380 381 class CrosDynamicSuiteException(Exception): 382 """ 383 Base class for exceptions coming from dynamic suite code in 384 server/cros/dynamic_suite/*. 385 """ 386 387 388 class StageBuildFailure(CrosDynamicSuiteException): 389 """Raised when the dev server throws 500 while staging a build.""" 390 391 392 class ControlFileEmpty(CrosDynamicSuiteException): 393 """Raised when the control file exists on the server, but can't be read.""" 394 395 396 class ControlFileMalformed(CrosDynamicSuiteException): 397 """Raised when an invalid control file is read.""" 398 399 400 class AsynchronousBuildFailure(CrosDynamicSuiteException): 401 """Raised when the dev server throws 500 while finishing staging of a build. 402 """ 403 404 405 class SuiteArgumentException(CrosDynamicSuiteException): 406 """Raised when improper arguments are used to run a suite.""" 407 408 409 class MalformedDependenciesException(CrosDynamicSuiteException): 410 """Raised when a build has a malformed dependency_info file.""" 411 412 413 class InadequateHostsException(CrosDynamicSuiteException): 414 """Raised when there are too few hosts to run a suite.""" 415 416 417 class NoHostsException(CrosDynamicSuiteException): 418 """Raised when there are no healthy hosts to run a suite.""" 419 420 421 class ControlFileNotFound(CrosDynamicSuiteException): 422 """Raised when a control file cannot be found and/or read.""" 423 424 425 class NoControlFileList(CrosDynamicSuiteException): 426 """Raised to indicate that a listing can't be done.""" 427 428 429 class SuiteControlFileException(CrosDynamicSuiteException): 430 """Raised when failing to list the contents of all control file.""" 431 432 433 class HostLockManagerReuse(CrosDynamicSuiteException): 434 """Raised when a caller tries to re-use a HostLockManager instance.""" 435 436 437 class ReimageAbortedException(CrosDynamicSuiteException): 438 """Raised when a Reimage job is aborted""" 439 440 441 class UnknownReimageType(CrosDynamicSuiteException): 442 """Raised when a suite passes in an invalid reimage type""" 443 444 445 class NoUniquePackageFound(Exception): 446 """Raised when an executable cannot be mapped back to a single package.""" 447 448 449 class RPCException(Exception): 450 """Raised when an RPC encounters an error that a client might wish to 451 handle specially.""" 452 453 454 class NoEligibleHostException(RPCException): 455 """Raised when no host could satisfy the requirements of a job.""" 456 457 458 class UnmodifiableLabelException(RPCException): 459 """Raised when an RPC tries to modify static labels.""" 460 461 462 class UnmodifiableAttributeException(RPCException): 463 """Raised when an RPC tries to modify static attributes.""" 464 465 466 class InvalidBgJobCall(Exception): 467 """Raised when an invalid call is made to a BgJob object.""" 468 469 470 class HeartbeatOnlyAllowedInShardModeException(Exception): 471 """Raised when a heartbeat is attempted but not allowed.""" 472 473 474 class UnallowedRecordsSentToMaster(Exception): 475 """Raised when an illegal record was sent from shard to master.""" 476 477 478 class IgnorableUnallowedRecordsSentToMaster(UnallowedRecordsSentToMaster): 479 """Raised when non-fatal illegal record was sent from shard. 480 481 This exception may be raised by rpc model logic on master, but will 482 not be returned back to heartbeat client. It indicates that some records 483 may have been illegal, but the master is ignoring those records and 484 proceeding with the rest of the heartbeat handling. 485 """ 486 487 488 class InvalidDataError(Exception): 489 """Exception raised when invalid data provided for database operation.""" 490 491 492 class ContainerError(Exception): 493 """Exception raised when program runs into error using container.""" 494 495 496 class IllegalUser(Exception): 497 """Exception raise when a program runs as an illegal user.""" 498 499 500 class AutoservDirectoryNotFoundError(AutoservHostError): 501 """Exception raised when an expected directory is not found.""" 502 503 504 class AutoservDiskSizeUnknownError(AutoservHostError): 505 """Exception raised when the disk space could not be determined.""" 506 507 508 # This MUST remain at the end of the file. 509 # Limit 'from error import *' to only import the exception instances. 510 for _name, _thing in locals().items(): 511 try: 512 if issubclass(_thing, Exception): 513 __all__.append(_name) 514 except TypeError: 515 pass # _thing not a class 516 __all__ = tuple(__all__) 517