# -*- mode:Python -*- # # This file is part of the Coriolis Software. # Copyright (c) Sorbonne Université 2012-2021, All Rights Reserved # # +-----------------------------------------------------------------+ # | C O R I O L I S | # | Alliance / Hurricane Interface | # | | # | Author : Jean-Paul Chaput | # | E-mail : Jean-Paul.Chaput@lip6.fr | # | =============================================================== | # | Python : "./crlcore/helpers/io.py" | # +-----------------------------------------------------------------+ import sys import os import os.path import re import traceback from .. import Cfg from ..Hurricane import UpdateSession from ..Viewer import Graphics, ErrorWidget def textStackTrace ( trace, showIndent=True, scriptPath=None ): indent = '' if showIndent: indent = ' ' s = '' if scriptPath: if len(scriptPath) > 100: filename = scriptPath[-100:] filename = '.../' + filename[ filename.find('/')+1 : ] if showIndent: s += '[ERROR] ' s += 'An exception occured while loading the Python script module:\n' s += indent + '\"{}\"\n' % (filename) s += indent + 'You should check for simple python errors in this module.\n\n' s += indent + 'Python stack trace:\n' maxdepth = len( trace ) for depth in range( maxdepth ): filename, line, function, code = trace[ maxdepth-depth-1 ] if len(filename) > 58: filename = filename[-58:] filename = '.../' + filename[ filename.find('/')+1 : ] #s += indent + '[%02d] %45s:%-5d in \"{}()\"' % ( maxdepth-depth-1, filename, line, function ) s += indent + '#{} in {:>25}() at {}:{}\n'.format( depth, function, filename, line ) return s def showStackTrace ( trace ): print( textStackTrace( trace, True )) return def textPythonTrace ( scriptPath=None, e=None, tryContinue=True ): s = '' if scriptPath: if len(scriptPath) > 100: filename = scriptPath[-100:] filename = '.../' + filename[ filename.find('/')+1 : ] else: filename = scriptPath s += '[ERROR] An exception occured while loading the Python script module:\n' s += ' \"{}\"\n'.format(filename) s += ' You should check for simple python errors in this module.\n' if isinstance(e,ErrorMessage): trace = e.trace s += textStackTrace( trace ) if e: s += ' Error was:\n' s += ' {}\n'.format(e) else: #trace = traceback.extract_tb( sys.exc_info()[2] ) print( traceback.format_exc() ) if tryContinue: s += ' Trying to continue anyway...' return s def showPythonTrace ( scriptPath=None, e=None, tryContinue=True ): print( textPythonTrace( scriptPath, e, tryContinue )) return # ------------------------------------------------------------------- # Class : "ErrorMessage". class ErrorMessage ( Exception ): def __init__ ( self, code, *arguments ): self.scriptPath = None self.trace = traceback.extract_stack() self.code = code self.errors = [ 'Malformed call to ErrorMessage().' , 'args:"{}"'.format(arguments) ] if not isinstance(self.code,int): self.errors = [ 'Malformed call to ErrorMessage(), first argument (code) must be an integer.' , 'code:"{}"'.format(code) , 'args:"{}"'.format(arguments) ] return text = None if len(arguments) == 1: if isinstance(arguments[0],Exception): text = str(arguments[0]).split('\n') else: self.errors = arguments[0] elif len(arguments) > 1: sys.stdout.flush() text = list(arguments) if text: self.errors = [] while len(text) == 0: del text[0] lstrip = 0 if text[0].startswith('[ERROR]'): lstrip = 8 for line in text: if line[0:lstrip] == ' '*lstrip or \ line[0:lstrip-1] == '[ERROR]': self.errors += [ line[lstrip:] ] else: self.errors += [ line.lstrip() ] sys.stdout.flush() return def __str__ ( self ): if not isinstance(self.errors,list): return "[ERROR] %s" % self.errors formatted = "\n" for i in range(len(self.errors)): if i == 0: formatted += "[ERROR] %s" % self.errors[i] else: formatted += " %s" % self.errors[i] if i+1 < len(self.errors): formatted += "\n" return formatted def getLinesAsString ( self ): if not isinstance(self.errors,list): return self.errors lines = '' for line in self.errors: lines += line + '\n' return lines def addMessage ( self, message ): if not isinstance(self.errors,list): self.errors = [ self.errors ] if isinstance(message,list): for line in message: self.errors += [ line ] else: self.errors += [ message ] return def terminate ( self ): print( self ) sys.exit( self.code ) @staticmethod def show ( code, *arguments ): e = ErrorMessage( code, *arguments ) if not Graphics.get().isEnabled(): raise e tryCont = ErrorWidget.run( e.getLinesAsString() , textStackTrace( e.trace, False, e.scriptPath )) if not tryCont: raise e return # ------------------------------------------------------------------- # Function : "catch()". # # Try to smartly display any exception on the TTY and the graphic # display, if available. def catch ( errorObject ): if isinstance(errorObject,ErrorMessage): em = errorObject else: em = ErrorMessage( 2, errorObject ) em.trace = traceback.extract_tb( sys.exc_info()[2] ) #em.scriptPath = __file__ print( em ) print( textStackTrace( em.trace, True, em.scriptPath )) if Graphics.get().isEnabled(): ErrorWidget.run( em.getLinesAsString() , textStackTrace( em.trace, False, em.scriptPath )) if UpdateSession.getStackSize() > 0: UpdateSession.close() return # ------------------------------------------------------------------- # Class : "WarningMessage". class WarningMessage ( Exception ): def __init__ ( self, message ): self._warnings = message return def __str__ ( self ): if not isinstance(self._warnings,list): return "[WARNING] %s" % self._warnings formatted = "\n" for i in range(len(self._warnings)): if i == 0: formatted += "[WARNING] %s" % self._warnings[i] else: formatted += " %s" % self._warnings[i] if i+1 < len(self._warnings): formatted += "\n" return formatted # ------------------------------------------------------------------- # Function : "vprint()". # # Small wrap around print to make use of the verbosity levels. def isVL ( level ): confLevel = 0 if Cfg.getParamBool('misc.verboseLevel1').asBool(): confLevel = 1 if Cfg.getParamBool('misc.verboseLevel2').asBool(): confLevel = 2 #print( 'level {} <= confLevel {}'.format(level,confLevel)) return level <= confLevel def vprint ( level, message ): if isVL(level): print( message ) return