PythonCaller Log does not show error line number (FME(R) 2024.1.1.0 (20240729 - Build 24619 - WIN64)
When python caller errors out. It does not show error line number.
Message Type: fme::internal::_v0::Exception Python Exception <GEOSException>: LocateFailureException: Could not locate vertex. 🟢06-Report (PythonFactory): PythonFactory failed to close properly
Page 1 / 1
What is triggering this error? Is it a PythonCaller, or a transformer that is part of FME?
If it’s a PythonCaller, can you please show the relevant part of the code.
Try removing the try...except block altogether. What you’re doing is effectively logging the error message but then ignoring the actual exception. It’s ofter better simply to let the exception raise itself, with all its details. That often leaves more possibilities for the Python interpreter to give a more detailed stack trace.
Alternatively, you can add “raise” on a new line under “logger.logMessageString(...” to re-raise the exception.
Sorry, forgot to mention that I added the try except after I got hold of the error line number. Would it be possible that it is because the code is not directly enclose in the def process_group The code is part of function that I define at the end of my python caller outside the class definition
You can try something like this to include more information in any exceptions occurring in your PythonCallers:
import fmeobjects import traceback
class FeatureProcessor(object): """Template Class Interface: When using this class, make sure its name is set as the value of the 'Class to Process Features' transformer parameter. """
def __init__(self): """Base constructor for class members.""" self.feature_count = 0 self.log = fmeobjects.FMELogFile()
def _log(self, message, severity=fmeobjects.FME_INFORM): """ Sends message to the FME log file and console window. Severity must be one of FME_INFORM, FME_WARN, FME_ERROR, FME_FATAL, FME_STATISTIC, or FME_STATUSREPORT. """ self.log.logMessageString(message, severity)
def input(self, feature): """This method is called for each FME Feature entering the PythonCaller. If knowledge of all input Features is not required for processing, then the processed Feature can be emitted from this method through self.pyoutput(). Otherwise, the input FME Feature should be cached to a list class member and processed in process_group() when 'Group by' attributes(s) are specified, or the close() method.
# ########################### # Your code goes here... # ###########################
self.pyoutput(feature)
except: self._log('='*78, fmeobjects.FME_ERROR) message = "{}({}) exception at feature number {}:".format( self.factory_name, self.__class__.__name__, self.feature_count) self._log(message, fmeobjects.FME_ERROR) self._log('-'*78, fmeobjects.FME_ERROR) for line in traceback.format_exc().splitlines(): self._log(line, fmeobjects.FME_ERROR) self._log('='*78, fmeobjects.FME_ERROR) if feature: self.log.logFeature(feature, fmeobjects.FME_ERROR) message = "An error occurred in {} method '{}'. See log for details.".format( self.factory_name, self.__class__.__name__) raise fmeobjects.FMEException(message)
As you can see, it uses the traceback module from the Python standard library to dump the entire stack trace with line numbers if an exception occurrs, then terminates your workspace.
Thank you. I will try that out and get back to you soon.
You can try something like this to include more information in any exceptions occurring in your PythonCallers:
import fmeobjects import traceback
class FeatureProcessor(object): """Template Class Interface: When using this class, make sure its name is set as the value of the 'Class to Process Features' transformer parameter. """
def __init__(self): """Base constructor for class members.""" self.feature_count = 0 self.log = fmeobjects.FMELogFile()
def _log(self, message, severity=fmeobjects.FME_INFORM): """ Sends message to the FME log file and console window. Severity must be one of FME_INFORM, FME_WARN, FME_ERROR, FME_FATAL, FME_STATISTIC, or FME_STATUSREPORT. """ self.log.logMessageString(message, severity)
def input(self, feature): """This method is called for each FME Feature entering the PythonCaller. If knowledge of all input Features is not required for processing, then the processed Feature can be emitted from this method through self.pyoutput(). Otherwise, the input FME Feature should be cached to a list class member and processed in process_group() when 'Group by' attributes(s) are specified, or the close() method.
# ########################### # Your code goes here... # ###########################
self.pyoutput(feature)
except: self._log('='*78, fmeobjects.FME_ERROR) message = "{}({}) exception at feature number {}:".format( self.factory_name, self.__class__.__name__, self.feature_count) self._log(message, fmeobjects.FME_ERROR) self._log('-'*78, fmeobjects.FME_ERROR) for line in traceback.format_exc().splitlines(): self._log(line, fmeobjects.FME_ERROR) self._log('='*78, fmeobjects.FME_ERROR) if feature: self.log.logFeature(feature, fmeobjects.FME_ERROR) message = "An error occurred in {} method '{}'. See log for details.".format( self.factory_name, self.__class__.__name__) raise fmeobjects.FMEException(message)
As you can see, it uses the traceback module from the Python standard library to dump the entire stack trace with line numbers if an exception occurrs, then terminates your workspace.
Thank you. It worked like a breeze.
Also, I noticed that I had Log Debug unchecked.
Now I get the error line number without using the traceback module.