[matter] add exception handler that also prints local variables in the stack
This commit is contained in:
@@ -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():
|
||||
|
||||
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user