Autotest: Add specified exception type to Retry for dev_server and servo

After adding ssh feature to dev_server and servo, we need to do retry
when meeting error.CmdError (ssh error). However a specified error type
needs to raised after retry, in order to be caught by its caller.

For example, a caller needs to call dev_server.get_control_file(). The ideal
case is we retry ssh connections to dev_server if it fails. When retry
is finished, we need it to raise a DevServerException, which is
currently caught by the caller.

This CL adds a specified exception to raise in retry, and also
refactors the error msg raising processes.

BUG=chromium:598496
TEST=Checked dev_server and servo raise the corresponding error types in
local autotest instance. Ran dev_server_unittest.

Change-Id: I53ad52b2c397beeb922d75539b63eaf9b6632c86
Reviewed-on: https://chromium-review.googlesource.com/335901
Commit-Ready: Xixuan Wu <xixuan@chromium.org>
Tested-by: Xixuan Wu <xixuan@chromium.org>
Reviewed-by: Xixuan Wu <xixuan@chromium.org>
diff --git a/client/common_lib/cros/retry.py b/client/common_lib/cros/retry.py
index def586b..64785ee 100644
--- a/client/common_lib/cros/retry.py
+++ b/client/common_lib/cros/retry.py
@@ -111,7 +111,8 @@
 
 
 
-def retry(ExceptionToCheck, timeout_min=1.0, delay_sec=3, blacklist=None):
+def retry(ExceptionToCheck, timeout_min=1.0, delay_sec=3, blacklist=None,
+          exception_to_raise=None):
     """Retry calling the decorated function using a delay with jitter.
 
     Will raise RPC ValidationError exceptions from the decorated
@@ -132,6 +133,8 @@
                       delays will be centered around this value, ranging up to
                       50% off this midpoint.
     @param blacklist: a list of exceptions that will be raised without retrying
+    @param exception_to_raise: the exception to raise. Callers can specify the
+    the exception they want to raise.
     """
     def deco_retry(func):
         random.seed()
@@ -184,8 +187,13 @@
 
             # The call must have timed out or raised ExceptionToCheck.
             if not exc_info:
-                raise error.TimeoutException('Call is timed out.')
+                if exception_to_raise:
+                    raise exception_to_raise('Call is timed out.')
+                else:
+                    raise error.TimeoutException('Call is timed out.')
             # Raise the cached exception with original backtrace.
+            if exception_to_raise:
+                raise exception_to_raise('%s: %s' % (exc_info[0], exc_info[1]))
             raise exc_info[0], exc_info[1], exc_info[2]