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