From 276bb913c81c3e3c60737ca79b0b7da6462a9c84 Mon Sep 17 00:00:00 2001 From: Vahid Hashemian Date: Mon, 30 Nov 2015 17:17:34 -0800 Subject: [PATCH] Add full stack trace for parser errors Along with each error returned as a result of validating a TOSCA resource provide the full stack trace to indicate the line of code that caught the error. Change-Id: I7e7a23005f5228795fe0da7f25ae8a99ada85c68 Closes-Bug: #1521320 --- toscaparser/common/exception.py | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/toscaparser/common/exception.py b/toscaparser/common/exception.py index d1fb43c6..f41b65c6 100644 --- a/toscaparser/common/exception.py +++ b/toscaparser/common/exception.py @@ -15,6 +15,7 @@ TOSCA exception classes ''' import logging import sys +import traceback from toscaparser.utils.gettextutils import _ @@ -133,6 +134,7 @@ class ExceptionCollector(object): def appendException(exception): if ExceptionCollector.collecting: if not ExceptionCollector.contains(exception): + exception.trace = traceback.extract_stack()[:-1] ExceptionCollector.exceptions.append(exception) else: raise exception @@ -142,24 +144,37 @@ class ExceptionCollector(object): return len(ExceptionCollector.exceptions) > 0 @staticmethod - def getExceptionReportEntry(exception): - return exception.__class__.__name__ + ': ' + str(exception) + def getTraceString(traceList): + traceString = '' + for entry in traceList: + f, l, m, c = entry[0], entry[1], entry[2], entry[3] + traceString += (_('\t\tFile %(file)s, line %(line)s, in ' + '%(method)s\n\t\t\t%(call)s\n') + % {'file': f, 'line': l, 'method': m, 'call': c}) + return traceString + + @staticmethod + def getExceptionReportEntry(exception, full=True): + entry = exception.__class__.__name__ + ': ' + str(exception) + if full: + entry += '\n' + ExceptionCollector.getTraceString(exception.trace) + return entry @staticmethod def getExceptions(): return ExceptionCollector.exceptions @staticmethod - def getExceptionsReport(): + def getExceptionsReport(full=True): report = [] for exception in ExceptionCollector.exceptions: report.append( - ExceptionCollector.getExceptionReportEntry(exception)) + ExceptionCollector.getExceptionReportEntry(exception, full)) return report @staticmethod def assertExceptionMessage(exception, message): err_msg = exception.__name__ + ': ' + message - report = ExceptionCollector.getExceptionsReport() + report = ExceptionCollector.getExceptionsReport(False) assert err_msg in report, (_('Could not find "%(msg)s" in "%(rep)s".') % {'rep': report.__str__(), 'msg': err_msg})