[matter] add exception handler that also prints local variables in the stack

This commit is contained in:
Fabio Erculiani
2013-01-06 16:37:11 +00:00
parent 8d110732d3
commit afccc337cc
2 changed files with 84 additions and 0 deletions

View File

@@ -22,6 +22,27 @@ from matter.lock import MatterResourceLock
from matter.output import purple, darkgreen, print_info, \
print_warning, print_error, is_stdout_a_tty, nocolor
from matter.spec import SpecParser, MatterSpec
from matter.utils import print_exception
def install_exception_handler():
sys.excepthook = handle_exception
def uninstall_exception_handler():
sys.excepthook = sys.__excepthook__
def handle_exception(exc_class, exc_instance, exc_tb):
# restore original exception handler, to avoid loops
uninstall_exception_handler()
if exc_class is KeyboardInterrupt:
raise SystemExit(1)
# always slap exception data (including stack content)
print_exception(tb_data = exc_tb)
def matter_main(binary_pms, nsargs, cwd, specs):
@@ -172,6 +193,7 @@ def main():
"""
Main App.
"""
install_exception_handler()
# disable color if standard output is not a TTY
if not is_stdout_a_tty():

View File

@@ -15,6 +15,8 @@ import sys
import tempfile
import traceback
from matter.output import print_generic
MATTER_TMPDIR = os.getenv("MATTER_TMPDIR", "/var/tmp/matter")
_ENCODING = "UTF-8"
@@ -31,6 +33,66 @@ def print_traceback(f = None):
traceback.print_exc(file = f)
def print_exception(silent=False, tb_data=None, all_frame_data=False):
"""
Print last Python exception and frame variables values (if available)
to stdout.
@keyword silent: do not print to stdout
@type silent: bool
@keyword tb_data: Python traceback object
@type tb_data: Python traceback instance
@keyword all_frame_data: print all variables in every frame
@type all_frame_data: bool
@return: exception data
@rtype: list of strings
"""
if not silent:
traceback.print_last()
data = []
if tb_data is not None:
tb = tb_data
else:
last_type, last_value, last_traceback = sys.exc_info()
tb = last_traceback
stack = []
while True:
if not tb:
break
if not tb.tb_next:
break
tb = tb.tb_next
if all_frame_data:
stack.append(tb.tb_frame)
if not all_frame_data:
stack.append(tb.tb_frame)
#if not returndata: print
for frame in stack:
if not silent:
print_generic("")
print_generic("Frame %s in %s at line %s" % (frame.f_code.co_name,
frame.f_code.co_filename, frame.f_lineno))
data.append("Frame %s in %s at line %s\n" % (frame.f_code.co_name,
frame.f_code.co_filename, frame.f_lineno))
for key, value in list(frame.f_locals.items()):
cur_str = ''
cur_str = "\t%20s = " % key
try:
cur_str += repr(value) + "\n"
except (AttributeError, NameError, TypeError):
cur_str += "<ERROR WHILE PRINTING VALUE>\n"
if not silent:
sys.stdout.write(cur_str)
data.append(cur_str)
return data
def mkstemp(prefix=None, suffix=None):
"""
Create temporary file into matter temporary directory.