Commits

woud...@4525493e-7705-40b1-a816-d608a930855b  committed 4de1a6c

added ErrorInfo and ErrorReport

  • Participants
  • Parent commits 8286a59

Comments (0)

Files changed (3)

+22-03-2006 Martin Woudstra
+	python/trferr.py:
+	    - added classes ErrorInfo and ErrorReport
+	    - added function typeName()
+	    - renamed messages to _typeNames
+	    - added error severity value constants
+	    - TransformError class can now return an ErrorInfo object
+	python/trf.py: start using ErrorInfo and ErrorReport. NOT FINISHED!
 20-03-2006 Martin Woudstra
 	python/trfutil.py: A
 	    - debugged functions append_path_env*, prepend_path_env*

File python/trf.py

         print self.getFullHelp()
         
 
+    def _handleException(self,e):
+        err = trferr.errorHandler.handleException(e)
+        err.setWho( 'JobTransform.%s' % self.name() )
+        return err    
+
+
     def ensureSkeleton(self):
         """Make sure that the skeleton jobOptions file can be found and/or auto-generated.
            In case of any problem, an exception is raised. If the function returns, all is OK."""
 
     def execute(self):
         """Execute transformation. Can only be called after the arguments have been set"""
+        self._logger.debug( 'Using %s' % ( trfenv.trfPath) )
         #clean up old stuff
         Filename.remove(trferr.exitStatusFile)
         Filename.remove(self.logFilename())
 
+        ErrorReport exeErrors
         try:
             # write the last command to file
             self.writeLastCommand()
                 exitFile.close()
 
             # exit is case of failure of athena
-            if status != 0: sys.exit( status )
-
-            # do all postRunActions
-            self.exePostRunActions()
+            if status != 0:
+                exeErrors.addInfo( self._handleErrorCode( ATHENA_FAILURE_ERROR ) )
+            else:
+                # do all postRunActions
+                self.exePostRunActions()
             
 
         # Catch all exceptions
-        except TransformError, e:
-            trferr.exit( e.exitStatus(), e.message )
-#        except exceptions.Exception, e:
-#            trferr.exit(trferr.UNKNOWN_EXCEPTION_RAISED, e.args)
-        else:
-            trferr.exit(trferr.TRF_OK)
-        
+        except exceptions.Exception, e:
+            exeErrors.addInfo( self._handleException(e) )
 
-        trferr.exit(trferr.UNKNOWN_ERROR)
-
+        return exeErrors
 
 
     def exeSysArgs(self):
         """Execute transformation using the command line arguments"""
-        self._logger.debug( 'Using %s' % ( trfenv.trfPath) )
         # process argument list
         try:
             self.processArgs(sys.argv[1:])
-        except TransformError, e:
-            trferr.exit( e.exitStatus(), e.message )
-            
-        # execute with filled arguments
-        self.execute()
+        except exceptions.exception,e:
+            return self._handleException(e)
+        else:
+            # execute with filled arguments
+            return self.execute()
 
 
+    def exeRunArgs(self, runArgs):
+        """Run transformation using arguments from a RunArguments object"""
+        # fill arguments
+        try:
+            for arg in self._positionalArgs:
+                name = arg.name()
+                if hasattr(runArgs,name):
+                    self.setArgument( name, getattr(runArgs,name) )
+        except exceptions.exception,e:
+            return self._handleException(e)
+        else:
+            # execute with filled arguments
+            return self.execute()
+
+
+    def exeArgDict(self, argDict):
+        """Run transformation using arguments from a dictionary"""
+        # fill arguments
+        try:
+            for arg in self._positionalArgs:
+                name = arg.name()
+                if name in argDict:
+                    self.setArgument( name, argDict[name] )
+        except exceptions.exception,e:
+            return self._handleException(e)
+        else:
+            # execute with filled arguments
+            return self.execute()
+
+                

File python/trferr.py

 
 __all__ = [ 'TransformError', 'TransformDefinitionError', 'TransformArgumentError',
             'TransformEnvError', 'InputFileError', 'OutputFileError',
-            'JobOptionsNotFoundError', 'TransformErrorHandler' ]
+            'JobOptionsNotFoundError', 'TransformErrorHandler',
+            'ErrorInfo', 'ErrorReport' ]
 
 exitStatusFile = 'exitstatus'
 
+# error severity values
+WARNING=3
+ERROR=2
+FATAL=1
+NO_ERROR=0
+
+# error type numbers
 TRF_OK = 0
 ATHENA_OK = 0
 ATHENA_FAILURE_ERROR = 1
 UNKNOWN_EXCEPTION_RAISED = 254
 UNKWOWN_ERROR = 255
 
-messages = { TRF_OK : 'OK' ,
-             ATHENA_FAILURE_ERROR     : 'AthenaExitWithFailure'  ,
-             ATHENA_LOAD_DLL_ERROR    : 'AthenaFailLoadLibrary' ,
-             KEYBOARD_INTERRUPT       : 'KeyboardInterrupt' ,
-             JOBOPTIONS_NOT_FOUND  : 'JobOptionsNotFound' ,
-             JOBOPTIONS_PYTHON_ERROR : 'JobOptionsPythonError' ,
-             TRF_INPUTFILE_ERROR   : 'TransformInputFileError'   ,
-             TRF_ARGUMENT_ERROR    : 'TransformArgumentError'    ,
-             TRF_DEFINITION_ERROR  : 'TransformDefinitionError'  ,
-             TRF_ENVIRONMENT_ERROR : 'TransformEnvironmentError' ,
-             TRF_OUTPUTFILE_ERROR  : 'TransformOutputFileError' ,
-             UNKNOWN_EXCEPTION_RAISED : 'UnknownExceptionError'  ,
-             UNKWOWN_ERROR            : 'UnknownError' }
+# error type names
+_typeNames = { TRF_OK : 'OK' ,
+              ATHENA_FAILURE_ERROR     : 'AthenaExitWithFailure'  ,
+              ATHENA_LOAD_DLL_ERROR    : 'AthenaFailLoadLibrary' ,
+              KEYBOARD_INTERRUPT       : 'KeyboardInterrupt' ,
+              JOBOPTIONS_NOT_FOUND  : 'JobOptionsNotFound' ,
+              JOBOPTIONS_PYTHON_ERROR : 'JobOptionsPythonError' ,
+              TRF_INPUTFILE_ERROR   : 'TransformInputFileError'   ,
+              TRF_ARGUMENT_ERROR    : 'TransformArgumentError'    ,
+              TRF_DEFINITION_ERROR  : 'TransformDefinitionError'  ,
+              TRF_ENVIRONMENT_ERROR : 'TransformEnvironmentError' ,
+              TRF_OUTPUTFILE_ERROR  : 'TransformOutputFileError' ,
+              UNKNOWN_EXCEPTION_RAISED : 'UnknownExceptionError'  ,
+              UNKWOWN_ERROR            : 'UnknownError' }
 
 
+def typeName(errorNum):
+    """function to convert error type number into a string"""
+    return _typeNames.get(errorNum,"UnknownErrorCode")
+    
+
 def exit(status=0,message=None):
-    statinfo = '%s %s' % (status,messages.get(status,'UnknownErrorCode'))
+    statinfo = '%s %s' % (status,typeName(status))
     if message: statinfo += ' # %s' % (message)
     if status: print 'ExitStatus: %s' % (statinfo)
     try:
         sys.exit(status)
 
 
+
+
+class ErrorInfo:
+    def __init__(self, who=None, number=0, severity=None, mess=None, backtrace=None, diagnosis=None):
+        self._who = who
+        self._number = number
+        self._type = typeName(number)
+        self._severity = severity
+        self._message = mess
+        self._diagnosis = diagnosis
+        self.setTracaback(backtrace)
+
+
+    def setWho(self,who):
+        self._who = who
+
+
+    def setSeverity(self,severity):
+        self._severity = severity
+        
+
+    def setBacktrace(self,backtrace=None):
+        if backtrace is None:
+            tb = sys.exc_info()[2]
+            if tb:
+                import traceback
+                backtrace = traceback.extract_tb(tb)
+        self._backtrace = backtrace
+        
+
+    def setDiagnosis(self,diag):
+        self._diagnosis = diag
+
+
+    def who(self):
+        return self._who
+
+
+    def number(self):
+        return self._number
+
+
+    def type(self):
+        return self._type
+
+
+    def severity(self):
+        return self._severity
+
+
+    def message(self):
+        return self._message
+
+
+    def diagnosis(self):
+        return self._diagnosis
+
+
+
+class ErrorReport:
+    def __init__(self,info=None):
+        self._whos = [ ]
+        self._fatals = [ ]
+        self._errors = [ ]
+        self._warnings = [ ]
+        self._fatalCount = { } # store per 'who'
+        self._errorCount = { } # store per 'who'
+        self._warningCount = { } # store per 'who'
+
+        if info is not None: self.addInfo(info)
+
+
+    def addFatal(self,info):
+        """add a Fatal. <info> is either an ErrorInfo object, or a string containing
+        the name of the one generating the error (the 'who')"""
+        if type(info) == type(''):
+            who = info
+        else:
+            who = info.who()
+
+        if who not in self._whos:
+            self._whos.append(who)
+
+        if who in self_.fatalCount:
+            self_.fatalCount[who] += 1
+        else:
+            self_.fatalCount[who] = 1
+            
+        if isinstance(info,ErrorInfo): self._fatals.append( info )
+
+
+    def addError(self,info):
+        """add a Error. <info> is either an ErrorInfo object, or a string containing
+        the name of the one generating the error."""
+        if type(info) == type(''):
+            who = info
+        else:
+            who = info.who()
+
+        if who not in self._whos:
+            self._whos.append(who)
+
+        if who in self_.errorCount:
+            self_.errorCount[who] += 1
+        else:
+            self_.errorCount[who] = 1
+            
+        if isinstance(info,ErrorInfo): self._errors.append( info )
+
+
+    def addWarning(self,info):
+        """add a Warning. <info> is either an ErrorInfo object, or a string containing
+        the name of the one generating the error."""
+        if type(info) == type(''):
+            who = info
+        else:
+            who = info.who()
+
+        if who not in self._whos:
+            self._whos.append(who)
+
+        if who in self_.warningCount:
+            self_.warningCount[who] += 1
+        else:
+            self_.warningCount[who] = 1
+            
+        if isinstance(info,ErrorInfo): self._warnings.append( info )
+
+        
+    def addInfo(self,info):
+        severity = info.severity()
+        if severity == FATAL:
+            self.addFatal( info )
+        elif severity == ERROR:
+            self.addError( info )
+        elif severity == WARNING:
+            self.addWarning( info )
+        elif severity == NO_ERROR:
+            pass
+        else:
+            print "ERROR: Unkown severity level in ErrorInfo:%s%s" % (os.linesep, info)
+        
+
+    def addReport(self,report):
+        # add the fatals
+        for err in report.fatals():   self.addFatal(err)
+        for err in report.errors():   self.addError(err)
+        for err in report.warnings(): self.addWarning(err)
+        
+
+    def whos(self):
+        return self._whos
+    
+
+    def fatals(self,who=None):
+        if who is None: return self._fatals
+        return [ e for e in self._fatals if e.who() == who ]
+
+
+    def errors(self,who=None):
+        if who is None: return self._errors
+        return [ e for e in self._errors if e.who() == who ]
+
+
+    def warnings(self,who=None):
+        if who is None: return self._warnings
+        return [ e for e in self._warnings if e.who() == who ]
+
+
+    def fatalCount(self,who=None):
+        sum = 0
+        if who is None:
+            for w in self._fatalCount:
+                sum = sum + self._fatalCount[w]
+        elif who in self._fatalCount:
+            sum = self._fatalCount[who]
+
+        return sum
+
+
+    def errorCount(self,who=None):
+        sum = 0
+        if who is None:
+            for w in self._errorCount:
+                sum = sum + self._errorCount[w]
+        elif who in self._errorCount:
+            sum = self._errorCount[who]
+
+        return sum
+
+
+    def warningCount(self,who=None):
+        sum = 0
+        if who is None:
+            for w in self._warningCount:
+                sum = sum + self._warningCount[w]
+        elif who in self._warningCount:
+            sum = self._warningCount[who]
+
+        return sum
+
+
+    def isOK(self):
+        return self.fatalCount() + self.errorCount() == 0
+
+
+
 class TransformError( exceptions.Exception ):
     """Base class for PyJobTransform Exception classes"""
     def __init__(self,msg=None,errnum=None):
     def __str__(self):
         return '%s %d: %s' % (self.__class__.__name__, self.errnum, self.message)
 
+
     def exitStatus(self):
         return self.errnum
 
 
+    def errorInfo(self):
+        return ErrorInfo(number=self.errnum,mess=self.message)
+
+
+
 class TransformDefinitionError( TransformError ):
     """Exception raised in case of an error in the definition of the transformation"""
     def __init__(self,message=None,errnum=TRF_DEFINITION_ERROR):
         TransformError.__init__(self,mess,errnum)
 
 
+
 class TransformErrorHandler:
     def __init__(self):
         self._name = self.__class__.__name__