title: Encapsulating an exception in Python
body: <p>How to decouple application from exceptions that creep in from used library dependencies?</p>
  
  <pre><code>[app] --uses--&gt; [lib] --dependson--&gt; [dependency]
                                             / /
    x- &lt;-propagates--o &lt;---throwsexception--' /
     \                                       /
      `-----needstohandle,soimports-----&gt; --'
  </code></pre>
  
  <p>The problem is from real <code>pip</code> code:</p>
  
  <ol>
  <li>module A (req/req_set.py) <a href="https://github.com/pypa/pip/blob/36a0187476b06d531426df7688d814770e030443/pip/req/req_set.py#L10" rel="nofollow noreferrer">depends on module B</a></li>
  <li>module B (download) <a href="https://github.com/pypa/pip/blob/36a0187476b06d531426df7688d814770e030443/pip/download.py#L26" rel="nofollow noreferrer">uses module C</a> (requests)</li>
  <li>module <a href="https://github.com/pypa/pip/blob/36a0187476b06d531426df7688d814770e030443/pip/req/req_set.py#L8" rel="nofollow noreferrer">A imports</a> module C <a href="https://github.com/pypa/pip/blob/36a0187476b06d531426df7688d814770e030443/pip/req/req_set.py#L363" rel="nofollow noreferrer">to handle exception from C</a></li>
  </ol>
  
  <p>How to encapsulate exception in module B? To remove dependency on C from module A? How to make sure that the cause and details of original exception are not lost? In other words how can I reraise the exception with a different name?</p>
  
  <p>The snippet below does what is needed, but it it Python 3 only:</p>
  
  <pre><code> try:
       dependency_call()
   except DependencyError as exc:
       raise LibraryError from exc
  </code></pre>
  
  <p><strong>UPDATE</strong>: I am looking for Python 2 compatible solution, the Python 3 added <code>raise ... from ...</code> that does the trick almost good.</p>
  
  <p><strong>UPDATE 2</strong>: The goal of encapsulating exception is to catch it in <code>[lib]</code> and re-throw a new one to <code>[app]</code> preserving the stack trace so that debug tools can still walk up the code (for human-only solution <a href="https://stackoverflow.com/a/26698747/239247">the answer by Alex Thornton</a> should be good).</p>