1# Copyright 2014 The Chromium Authors. All rights reserved.
2# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
4
5"""
6Exception classes raised by AdbWrapper and DeviceUtils.
7"""
8
9from devil import base_error
10from devil.utils import cmd_helper
11
12
13class CommandFailedError(base_error.BaseError):
14  """Exception for command failures."""
15
16  def __init__(self, message, device_serial=None):
17    if device_serial is not None:
18      message = '(device: %s) %s' % (device_serial, message)
19    self.device_serial = device_serial
20    super(CommandFailedError, self).__init__(message)
21
22
23class _BaseCommandFailedError(CommandFailedError):
24  """Base Exception for adb and fastboot command failures."""
25
26  def __init__(self, args, output, status=None, device_serial=None,
27               message=None):
28    self.args = args
29    self.output = output
30    self.status = status
31    if not message:
32      adb_cmd = ' '.join(cmd_helper.SingleQuote(arg) for arg in self.args)
33      message = ['adb %s: failed ' % adb_cmd]
34      if status:
35        message.append('with exit status %s ' % self.status)
36      if output:
37        message.append('and output:\n')
38        message.extend('- %s\n' % line for line in output.splitlines())
39      else:
40        message.append('and no output.')
41      message = ''.join(message)
42    super(_BaseCommandFailedError, self).__init__(message, device_serial)
43
44
45class AdbCommandFailedError(_BaseCommandFailedError):
46  """Exception for adb command failures."""
47
48  def __init__(self, args, output, status=None, device_serial=None,
49               message=None):
50    super(AdbCommandFailedError, self).__init__(
51        args, output, status=status, message=message,
52        device_serial=device_serial)
53
54
55class FastbootCommandFailedError(_BaseCommandFailedError):
56  """Exception for fastboot command failures."""
57
58  def __init__(self, args, output, status=None, device_serial=None,
59               message=None):
60    super(FastbootCommandFailedError, self).__init__(
61        args, output, status=status, message=message,
62        device_serial=device_serial)
63
64
65class DeviceVersionError(CommandFailedError):
66  """Exception for device version failures."""
67
68  def __init__(self, message, device_serial=None):
69    super(DeviceVersionError, self).__init__(message, device_serial)
70
71
72class AdbShellCommandFailedError(AdbCommandFailedError):
73  """Exception for shell command failures run via adb."""
74
75  def __init__(self, command, output, status, device_serial=None):
76    self.command = command
77    message = ['shell command run via adb failed on the device:\n',
78               '  command: %s\n' % command]
79    message.append('  exit status: %s\n' % status)
80    if output:
81      message.append('  output:\n')
82      if isinstance(output, basestring):
83        output_lines = output.splitlines()
84      else:
85        output_lines = output
86      message.extend('  - %s\n' % line for line in output_lines)
87    else:
88      message.append("  output: ''\n")
89    message = ''.join(message)
90    super(AdbShellCommandFailedError, self).__init__(
91      ['shell', command], output, status, device_serial, message)
92
93
94class CommandTimeoutError(base_error.BaseError):
95  """Exception for command timeouts."""
96  pass
97
98
99class DeviceUnreachableError(base_error.BaseError):
100  """Exception for device unreachable failures."""
101  pass
102
103
104class NoDevicesError(base_error.BaseError):
105  """Exception for having no devices attached."""
106
107  def __init__(self):
108    super(NoDevicesError, self).__init__(
109        'No devices attached.', is_infra_error=True)
110
111
112class NoAdbError(base_error.BaseError):
113  """Exception for being unable to find ADB."""
114
115  def __init__(self, msg=None):
116    super(NoAdbError, self).__init__(
117        msg or 'Unable to find adb.', is_infra_error=True)
118
119
120class DeviceChargingError(CommandFailedError):
121  """Exception for device charging errors."""
122
123  def __init__(self, message, device_serial=None):
124    super(DeviceChargingError, self).__init__(message, device_serial)
125