Revision 1576
Added by Aaron Marcuse-Kubitza almost 13 years ago
lib/exc.py | ||
---|---|---|
18 | 18 |
return sys.exc_info()[2] |
19 | 19 |
# can't just return pointer to traceback because it will change :-( |
20 | 20 |
|
21 |
def has_traceback(e): return hasattr(e, 'traceback_')
|
|
21 |
def has_tracebacks(e): return hasattr(e, 'tracebacks')
|
|
22 | 22 |
|
23 | 23 |
def add_traceback(e): |
24 | 24 |
'''Adds current traceback to an exception if it doesn't already have one''' |
25 | 25 |
traceback_ = sys_traceback() # get first in case later code throws exception |
26 |
if not has_traceback(e): e.traceback_ = traceback_ |
|
26 |
if not has_tracebacks(e): e.tracebacks = [] |
|
27 |
if util.list_get(e.tracebacks, 0) == traceback_: return |
|
28 |
e.tracebacks.insert(0, traceback_) # tracebacks have most recent call last |
|
27 | 29 |
|
28 |
def get_traceback_str(e): |
|
29 |
try: traceback_ = e.traceback_ |
|
30 |
except AttributeError: return '' |
|
30 |
def get_traceback_str(traceback_): |
|
31 | 31 |
return ''.join(traceback.format_exception(None, None, traceback_)[:-1]) |
32 | 32 |
# remove final "None" line ("exception name") |
33 | 33 |
|
34 |
def get_e_tracebacks_str(e): |
|
35 |
try: tracebacks = e.tracebacks |
|
36 |
except AttributeError: return '' |
|
37 |
return ''.join(get_traceback_str(t) for t in tracebacks) |
|
38 |
|
|
34 | 39 |
def add_msg(e, msg): e.args = (strings.ensure_newl(str(e))+msg,) |
35 | 40 |
|
36 | 41 |
def repl_msg(e, **repls): e.args = (str(e) % repls,) |
... | ... | |
46 | 51 |
def str_(e): return ''.join(traceback.format_exception_only(type(e), e)) |
47 | 52 |
|
48 | 53 |
def print_ex(e, emph=True): |
49 |
msg = strings.ensure_newl(str_(e))+get_traceback_str(e)
|
|
54 |
msg = strings.ensure_newl(str_(e))+get_e_tracebacks_str(e)
|
|
50 | 55 |
if emph: |
51 | 56 |
first_line, nl, rest = msg.partition('\n') |
52 | 57 |
msg = term.error(first_line)+nl+rest |
Also available in: Unified diff
exc.py: Changed to store multiple tracebacks in an exception, in case an exception is caught and re-raised inside an ExceptionWithCause wrapper. This preserves more of the traceback in this situation, because you get the ExceptionWithCause's traceback as well.