[tor-commits] [stem/master] Don't obscure tracebacks by re-raising exceptions

atagar at torproject.org atagar at torproject.org
Tue Jun 16 17:09:36 UTC 2015


commit 980022bb0dab1daf35f23b681121dce125301c28
Author: Damian Johnson <atagar at torproject.org>
Date:   Tue Jun 16 09:24:47 2015 -0700

    Don't obscure tracebacks by re-raising exceptions
    
    Interesting! If you call just 'raise' in a catch block you can re-raise the
    caught exception with the original stracktrace...
    
      https://stackoverflow.com/questions/4825234/exception-traceback-is-hidden-if-not-re-raised-immediately
    
    Perfect! This is especially useful for our @with_default decorator.
---
 docs/change_log.rst          |    1 +
 stem/connection.py           |   12 ++++++------
 stem/control.py              |   30 +++++++++++++++---------------
 stem/descriptor/__init__.py  |    8 ++++----
 stem/interpreter/commands.py |    2 +-
 stem/socket.py               |    8 ++++----
 stem/util/proc.py            |    2 +-
 stem/util/system.py          |    4 +++-
 8 files changed, 35 insertions(+), 32 deletions(-)

diff --git a/docs/change_log.rst b/docs/change_log.rst
index aea62a2..a6529fd 100644
--- a/docs/change_log.rst
+++ b/docs/change_log.rst
@@ -48,6 +48,7 @@ The following are only available within Stem's `git repository
   * :func:`~stem.connection.connect` and :func:`~stem.control.Controller.from_port` now connect to both port 9051 (relay's default) and 9151 (Tor Browser's default) (:trac:`16075`)
   * Added `support for NETWORK_LIVENESS events <api/response.html#stem.response.events.NetworkLivenessEvent>`_ (:spec:`44aac63`)
   * IPv6 addresses could trigger errors in :func:`~stem.control.Controller.get_listeners`, :class:`~stem.response.events.ORConnEvent`, and quite a few other things (:trac:`16174`)
+  * Don't obscure stacktraces, most notably :class:`~stem.control.Controller` getter methods with default values
 
  * **Descriptors**
 
diff --git a/stem/connection.py b/stem/connection.py
index 30d7b41..53bfc5d 100644
--- a/stem/connection.py
+++ b/stem/connection.py
@@ -665,7 +665,7 @@ def authenticate_none(controller, suppress_ctl_errors = True):
       pass
 
     if not suppress_ctl_errors:
-      raise exc
+      raise
     else:
       raise OpenAuthRejected('Socket failed (%s)' % exc)
 
@@ -735,7 +735,7 @@ def authenticate_password(controller, password, suppress_ctl_errors = True):
       pass
 
     if not suppress_ctl_errors:
-      raise exc
+      raise
     else:
       raise PasswordAuthRejected('Socket failed (%s)' % exc)
 
@@ -825,7 +825,7 @@ def authenticate_cookie(controller, cookie_path, suppress_ctl_errors = True):
       pass
 
     if not suppress_ctl_errors:
-      raise exc
+      raise
     else:
       raise CookieAuthRejected('Socket failed (%s)' % exc, cookie_path, False)
 
@@ -922,7 +922,7 @@ def authenticate_safecookie(controller, cookie_path, suppress_ctl_errors = True)
       pass
 
     if not suppress_ctl_errors:
-      raise exc
+      raise
     else:
       raise AuthChallengeFailed('Socket failed (%s)' % exc, cookie_path, True)
 
@@ -930,7 +930,7 @@ def authenticate_safecookie(controller, cookie_path, suppress_ctl_errors = True)
     stem.response.convert('AUTHCHALLENGE', authchallenge_response)
   except stem.ProtocolError as exc:
     if not suppress_ctl_errors:
-      raise exc
+      raise
     else:
       raise AuthChallengeFailed('Unable to parse AUTHCHALLENGE response: %s' % exc, cookie_path)
 
@@ -954,7 +954,7 @@ def authenticate_safecookie(controller, cookie_path, suppress_ctl_errors = True)
       pass
 
     if not suppress_ctl_errors:
-      raise exc
+      raise
     else:
       raise CookieAuthRejected('Socket failed (%s)' % exc, cookie_path, True, auth_response)
 
diff --git a/stem/control.py b/stem/control.py
index 8b0363f..f08a455 100644
--- a/stem/control.py
+++ b/stem/control.py
@@ -409,11 +409,11 @@ def with_default(yields = False):
       def wrapped(self, *args, **kwargs):
         try:
           return func(self, *args, **kwargs)
-        except Exception as exc:
+        except:
           default = get_default(func, args, kwargs)
 
           if default == UNDEFINED:
-            raise exc
+            raise
           else:
             return default
     else:
@@ -422,11 +422,11 @@ def with_default(yields = False):
         try:
           for val in func(self, *args, **kwargs):
             yield val
-        except Exception as exc:
+        except:
           default = get_default(func, args, kwargs)
 
           if default == UNDEFINED:
-            raise exc
+            raise
           else:
             if default is not None:
               for val in default:
@@ -572,14 +572,14 @@ class BaseController(object):
             self._post_authentication()
 
           return response
-      except stem.SocketClosed as exc:
+      except stem.SocketClosed:
         # If the recv() thread caused the SocketClosed then we could still be
         # in the process of closing. Calling close() here so that we can
         # provide an assurance to the caller that when we raise a SocketClosed
         # exception we are shut down afterward for realz.
 
         self.close()
-        raise exc
+        raise
 
   def is_alive(self):
     """
@@ -1125,7 +1125,7 @@ class Controller(BaseController):
 
       log.debug('GETINFO %s (failed: %s)' % (' '.join(params), exc))
 
-      raise exc
+      raise
 
   @with_default()
   def get_version(self, default = UNDEFINED):
@@ -1545,7 +1545,7 @@ class Controller(BaseController):
       if str(exc).startswith('GETINFO request contained unrecognized keywords:'):
         raise stem.DescriptorUnavailable("Tor was unable to provide the descriptor for '%s'" % relay)
       else:
-        raise exc
+        raise
 
     if not desc_content:
       raise stem.DescriptorUnavailable('Descriptor information is unavailable, tor might still be downloading it')
@@ -1653,7 +1653,7 @@ class Controller(BaseController):
         if str(exc).startswith('GETINFO request contained unrecognized keywords:'):
           raise stem.DescriptorUnavailable("Tor was unable to provide the descriptor for '%s'" % relay)
         else:
-          raise exc
+          raise
 
       if not desc_content:
         raise stem.DescriptorUnavailable('Descriptor information is unavailable, tor might still be downloading it')
@@ -1663,7 +1663,7 @@ class Controller(BaseController):
       if not self._is_server_descriptors_available():
         raise ValueError(SERVER_DESCRIPTORS_UNSUPPORTED)
 
-      raise exc
+      raise
 
   @with_default(yields = True)
   def get_server_descriptors(self, default = UNDEFINED):
@@ -1775,7 +1775,7 @@ class Controller(BaseController):
       if str(exc).startswith('GETINFO request contained unrecognized keywords:'):
         raise stem.DescriptorUnavailable("Tor was unable to provide the descriptor for '%s'" % relay)
       else:
-        raise exc
+        raise
 
     if not desc_content:
       raise stem.DescriptorUnavailable('Descriptor information is unavailable, tor might still be downloading it')
@@ -2090,7 +2090,7 @@ class Controller(BaseController):
       if default != UNDEFINED:
         return dict((param, default) for param in params)
       else:
-        raise exc
+        raise
 
   def _get_conf_dict_to_response(self, config_dict, default, multiple):
     """
@@ -2280,7 +2280,7 @@ class Controller(BaseController):
                 (time.time() - start_time))
     except stem.ControllerError as exc:
       log.debug('GETCONF HiddenServiceOptions (failed: %s)' % exc)
-      raise exc
+      raise
 
     service_dir_map = OrderedDict()
     directory = None
@@ -2579,14 +2579,14 @@ class Controller(BaseController):
         result += self.get_info('onions/current').split('\n')
       except stem.ProtocolError as exc:
         if 'No onion services of the specified type.' not in str(exc):
-          raise exc
+          raise
 
     if detached:
       try:
         result += self.get_info('onions/detached').split('\n')
       except stem.ProtocolError as exc:
         if 'No onion services of the specified type.' not in str(exc):
-          raise exc
+          raise
 
     return result
 
diff --git a/stem/descriptor/__init__.py b/stem/descriptor/__init__.py
index e8b581e..719ee84 100644
--- a/stem/descriptor/__init__.py
+++ b/stem/descriptor/__init__.py
@@ -489,9 +489,9 @@ class Descriptor(object):
               line += '\n%s' % block_contents
 
             self._unrecognized_lines.append(line)
-      except ValueError as exc:
+      except ValueError:
         if validate:
-          raise exc
+          raise
 
   def _set_path(self, path):
     self._path = path
@@ -821,11 +821,11 @@ def _get_descriptor_components(raw_contents, validate, extra_keywords = ()):
         block_type, block_contents = block_attr
       else:
         block_type, block_contents = None, None
-    except ValueError as exc:
+    except ValueError:
       if not validate:
         continue
 
-      raise exc
+      raise
 
     if keyword in extra_keywords:
       extra_entries.append('%s %s' % (keyword, value))
diff --git a/stem/interpreter/commands.py b/stem/interpreter/commands.py
index ffca9ab..368a81e 100644
--- a/stem/interpreter/commands.py
+++ b/stem/interpreter/commands.py
@@ -345,7 +345,7 @@ class ControlInterpretor(code.InteractiveConsole):
             output = format(self._controller.msg(command).raw_content().strip(), *STANDARD_OUTPUT)
           except stem.ControllerError as exc:
             if isinstance(exc, stem.SocketClosed):
-              raise exc
+              raise
             else:
               output = format(str(exc), *ERROR_OUTPUT)
 
diff --git a/stem/socket.py b/stem/socket.py
index b2b960f..1592786 100644
--- a/stem/socket.py
+++ b/stem/socket.py
@@ -122,14 +122,14 @@ class ControlSocket(object):
           raise stem.SocketClosed()
 
         send_message(self._socket_file, message, raw)
-      except stem.SocketClosed as exc:
+      except stem.SocketClosed:
         # if send_message raises a SocketClosed then we should properly shut
         # everything down
 
         if self.is_alive():
           self.close()
 
-        raise exc
+        raise
 
   def recv(self):
     """
@@ -154,7 +154,7 @@ class ControlSocket(object):
           raise stem.SocketClosed()
 
         return recv_message(socket_file)
-      except stem.SocketClosed as exc:
+      except stem.SocketClosed:
         # If recv_message raises a SocketClosed then we should properly shut
         # everything down. However, there's a couple cases where this will
         # cause deadlock...
@@ -174,7 +174,7 @@ class ControlSocket(object):
             self.close()
             self._send_lock.release()
 
-        raise exc
+        raise
 
   def is_alive(self):
     """
diff --git a/stem/util/proc.py b/stem/util/proc.py
index a03b83b..b67b011 100644
--- a/stem/util/proc.py
+++ b/stem/util/proc.py
@@ -508,7 +508,7 @@ def _get_lines(file_path, line_prefixes, parameter):
       return results
   except IOError as exc:
     _log_failure(parameter, exc)
-    raise exc
+    raise
 
 
 def _log_runtime(parameter, proc_location, start_time):
diff --git a/stem/util/system.py b/stem/util/system.py
index eb7b9ad..4f74f81 100644
--- a/stem/util/system.py
+++ b/stem/util/system.py
@@ -953,6 +953,8 @@ def files_with_suffix(base_path, suffix):
 
 def call(command, default = UNDEFINED, ignore_exit_status = False):
   """
+  call(command, default = UNDEFINED, ignore_exit_status = False)
+
   Issues a command in a subprocess, blocking until completion and returning the
   results. This is not actually ran in a shell so pipes and other shell syntax
   are not permitted.
@@ -1007,7 +1009,7 @@ def call(command, default = UNDEFINED, ignore_exit_status = False):
     if default != UNDEFINED:
       return default
     else:
-      raise exc
+      raise
 
 
 def get_process_name():



More information about the tor-commits mailing list