I believe a better idea is to use 

    raise NewException("Explain why") from CatchedException

pattern. In particular, considering Python 3 and the example given by @BrenBarn I use following 

    def failure():
        raise ValueError("Real error")

    try:
        failure()
    except ValueError as ex:
        raise TypeError("Apology error") from ex

which yields 

    --------------------------------------------------------------------------- ValueError                                Traceback (most recent call last) ~\AppData\Local\Temp\ipykernel_15716\1525308893.py in <module>
          4 try:
    ----> 5     failure()
          6 except ValueError as ex:
    
    ~\AppData\Local\Temp\ipykernel_15716\1525308893.py in failure()
          1 def failure():
    ----> 2     raise ValueError("Real error")
          3 
    
    ValueError: Real error
    
    The above exception was the direct cause of the following exception:
    
    TypeError                                 Traceback (most recent call last) ~\AppData\Local\Temp\ipykernel_15716\1525308893.py in <module>
          5     failure()
          6 except ValueError as ex:
    ----> 7     raise TypeError("Apology error") from ex
    
    TypeError: Apology error