"""
Print the Environment of a Text Body
"""
+ error = []
# print the environment of the method
min_line = max(1, line-4)
max_line = min(line + 4, len(body))
- for i in xrange(min_line, max_line + 1):
+ for i in range(min_line, max_line + 1):
if line == i:
- logger.error(' *** %.4d:%s', i, body[i-1])
+ error.append(' *** %.4d:%s' % (i, body[i-1].rstrip()))
else:
- logger.error(' %.4d:%s', i, body[i-1])
+ error.append(' %.4d:%s' % (i, body[i-1].rstrip()))
+ return error
def better_compile(text, file, realfile, mode = "exec"):
"""
if e.lineno:
logger.error("The lines leading to this error were:")
logger.error("\t%d:%s:'%s'", e.lineno, e.__class__.__name__, body[e.lineno-1])
- _print_trace(body, e.lineno)
+ logger.error("\n".join(_print_trace(body, e.lineno)))
else:
logger.error("The function causing this error was:")
for line in body:
e = bb.BBHandledException(e)
raise e
-def better_exec(code, context, text = None, realfile = "<code>"):
- """
- Similiar to better_compile, better_exec will
- print the lines that are responsible for the
- error.
- """
- import bb.parse
- if not text:
- text = code
- if not hasattr(code, "co_filename"):
- code = better_compile(code, realfile, realfile)
+def _print_exception(t, value, tb, realfile, text, context):
+ error = []
try:
- exec(code, _context, context)
- except Exception as e:
- (t, value, tb) = sys.exc_info()
-
- if t in [bb.parse.SkipPackage, bb.build.FuncFailed]:
- raise
-
import traceback
exception = traceback.format_exception_only(t, value)
- logger.error('Error executing a python function in %s:\n%s',
- realfile, ''.join(exception))
+ error.append('Error executing a python function in %s:\n' % realfile)
# Strip 'us' from the stack (better_exec call)
tb = tb.tb_next
textarray = text.split('\n')
- linefailed = traceback.tb_lineno(tb)
- tbextract = traceback.extract_tb(tb)
- tbformat = "\n".join(traceback.format_list(tbextract))
- logger.error("The stack trace of python calls that resulted in this exception/failure was:")
- for line in tbformat.split('\n'):
- logger.error(line)
+ linefailed = tb.tb_lineno
- logger.error("The code that was being executed was:")
- _print_trace(textarray, linefailed)
- logger.error("[From file: '%s', lineno: %s, function: %s]", tbextract[0][0], tbextract[0][1], tbextract[0][2])
+ tbextract = traceback.extract_tb(tb)
+ tbformat = traceback.format_list(tbextract)
+ error.append("The stack trace of python calls that resulted in this exception/failure was:")
+ error.append("File: '%s', lineno: %s, function: %s" % (tbextract[0][0], tbextract[0][1], tbextract[0][2]))
+ error.extend(_print_trace(textarray, linefailed))
# See if this is a function we constructed and has calls back into other functions in
# "text". If so, try and improve the context of the error by diving down the trace
level = 0
nexttb = tb.tb_next
while nexttb is not None and (level+1) < len(tbextract):
+ error.append("File: '%s', lineno: %s, function: %s" % (tbextract[level+1][0], tbextract[level+1][1], tbextract[level+1][2]))
if tbextract[level][0] == tbextract[level+1][0] and tbextract[level+1][2] == tbextract[level][0]:
- _print_trace(textarray, tbextract[level+1][1])
- logger.error("[From file: '%s', lineno: %s, function: %s]", tbextract[level+1][0], tbextract[level+1][1], tbextract[level+1][2])
+ # The code was possibly in the string we compiled ourselves
+ error.extend(_print_trace(textarray, tbextract[level+1][1]))
+ elif tbextract[level+1][0].startswith("/"):
+ # The code looks like it might be in a file, try and load it
+ try:
+ with open(tbextract[level+1][0], "r") as f:
+ text = f.readlines()
+ error.extend(_print_trace(text, tbextract[level+1][1]))
+ except:
+ error.append(tbformat[level+1])
elif "d" in context and tbextract[level+1][2]:
+ # Try and find the code in the datastore based on the functionname
d = context["d"]
functionname = tbextract[level+1][2]
text = d.getVar(functionname, True)
if text:
- _print_trace(text.split('\n'), tbextract[level+1][1])
- logger.error("[From file: '%s', lineno: %s, function: %s]", tbextract[level+1][0], tbextract[level+1][1], tbextract[level+1][2])
+ error.extend(_print_trace(text.split('\n'), tbextract[level+1][1]))
else:
- break
+ error.append(tbformat[level+1])
else:
- break
+ error.append(tbformat[level+1])
nexttb = tb.tb_next
level = level + 1
+ error.append("Exception: %s" % ''.join(exception))
+ finally:
+ logger.error("\n".join(error))
+
+def better_exec(code, context, text = None, realfile = "<code>"):
+ """
+ Similiar to better_compile, better_exec will
+ print the lines that are responsible for the
+ error.
+ """
+ import bb.parse
+ if not text:
+ text = code
+ if not hasattr(code, "co_filename"):
+ code = better_compile(code, realfile, realfile)
+ try:
+ exec(code, _context, context)
+ except Exception as e:
+ (t, value, tb) = sys.exc_info()
+
+ if t in [bb.parse.SkipPackage, bb.build.FuncFailed]:
+ raise
+ try:
+ _print_exception(t, value, tb, realfile, text, context)
+ except Exception as e:
+ logger.error("Exception handler error: %s" % str(e))
+
e = bb.BBHandledException(e)
raise e