import sys


class WrapperException(Exception):
    def __init__(self, msg):
        Exception.__init__(self, msg)
        self.info = sys.exc_info()
        
    def unwrap(self):
        """ unwrap the original exception data
        
        Return tuple (type, value, list)
        
        The list contain the complete stack up to the wrapped
        exception, excluding the frame of the wrapper itself. The list
        can be formatted using traceback.format_list.
        """
        import traceback
        stackUpToWrapper = traceback.extract_tb(sys.exc_info()[2])[:-1]
        type, value, tb = self.info
        wrappedStack = traceback.extract_tb(tb)
        del tb
        return type, value, stackUpToWrapper + wrappedStack


def first():
    second()
    
def second():
    third()
    
def third():
    # Wrap exceptions 
    try:
        forth()
    except ValueError:
        raise WrapperException('Fatal error! Try to be more carful '
                               'with your splits.')
                               
def forth():
    lowLevel()
                               
def lowLevel():
    # Error at low level    
    a, b = ''.split()
 
try:
    first()
except WrapperException, wrapper:
    import traceback
    # Show the wrapper exception
    traceback.print_exc()
    print
    
    # Show the wrapped exception
    type, value, list = wrapper.unwrap()
    print 'Traceback (most recent call last):'
    print ''.join(traceback.format_list(list))
    print ''.join(traceback.format_exception_only(type, value))
    
