def format_stack_report(details, exc_info): header = '' header += "Exception\n---------\n" if exc_info: header += ''.join(traceback.format_exception(*exc_info)) header += "\n" # Print out a stack trace too. The exception stack only contains # calls between the try and the exception. try: stack = util.get_nice_stack() except StandardError: stack = traceback.extract_stack() header += "Call Stack\n---------\n" header += ''.join(traceback.format_list(stack)) header += "\n" else: # fake an exception with our call stack try: stack = util.get_nice_stack() except StandardError: stack = traceback.extract_stack() header += ''.join(traceback.format_list(stack)) header += 'UnknownError: %s\n' % details header += "\n" return header
def format_crash_report(when, exc_info, details): header = "" header += "App: %s\n" % app.config.get(prefs.LONG_APP_NAME) header += "Publisher: %s\n" % app.config.get(prefs.PUBLISHER) header += "Platform: %s\n" % app.config.get(prefs.APP_PLATFORM) header += "Python: %s\n" % sys.version.replace("\r\n"," ").replace("\n"," ").replace("\r"," ") header += "Py Path: %s\n" % repr(sys.path) header += "Version: %s\n" % app.config.get(prefs.APP_VERSION) header += "Serial: %s\n" % app.config.get(prefs.APP_SERIAL) header += "Revision: %s\n" % app.config.get(prefs.APP_REVISION) header += "Builder: %s\n" % app.config.get(prefs.BUILD_MACHINE) header += "Build Time: %s\n" % app.config.get(prefs.BUILD_TIME) header += "Time: %s\n" % time.asctime() header += "When: %s\n" % when header += "\n" if exc_info: header += "Exception\n---------\n" header += ''.join(traceback.format_exception(*exc_info)) header += "\n" if details: header += "Details: %s\n" % (details, ) header += "Call stack\n----------\n" try: stack = util.get_nice_stack() except (SystemExit, KeyboardInterrupt): raise except: stack = traceback.extract_stack() header += ''.join(traceback.format_list(stack)) header += "\n" header += "Threads\n-------\n" header += "Current: %s\n" % threading.currentThread().getName() header += "Active:\n" for t in threading.enumerate(): header += " - %s%s\n" % \ (t.getName(), t.isDaemon() and ' [Daemon]' or '') # Combine the header with the logfile contents, if available, to # make the dialog box crash message. {{{ and }}} are Trac # Wiki-formatting markers that force a fixed-width font when the # report is pasted into a ticket. report = "{{{\n%s}}}\n" % header def read_log(logFile, logName="Log"): try: f = open(logFile, "rt") logContents = "%s\n---\n" % logName logContents += f.read() f.close() except (SystemExit, KeyboardInterrupt): raise except: logContents = '' return logContents logFile = app.config.get(prefs.LOG_PATHNAME) downloaderLogFile = app.config.get(prefs.DOWNLOADER_LOG_PATHNAME) if logFile is None: logContents = "No logfile available on this platform.\n" else: logContents = read_log(logFile) if downloaderLogFile is not None: if logContents is not None: logContents += "\n" + read_log(downloaderLogFile, "Downloader Log") else: logContents = read_log(downloaderLogFile) if logContents is not None: report += "{{{\n%s}}}\n" % util.stringify(logContents) # Dump the header for the report we just generated to the log, in # case there are multiple failures or the user sends in the log # instead of the report from the dialog box. (Note that we don't # do this until we've already read the log into the dialog # message.) logging.info ("----- CRASH REPORT (DANGER CAN HAPPEN) -----") logging.info (header) logging.info ("----- END OF CRASH REPORT -----") return report