I'm trying to understand how the ordering works in the Python Toolbox.

What I need is, everytime the user updates the parameter, the tool will check if a feature exists there, and display an error immediately if it doesn't.

But the setErrorMessage on my parameter inside updateParameters is not actually putting the parameter in error state, so I'm not sure what to do here, the documentation even shows that this is the way to do it.

Tool code :

class CustomTool(object):

expected_class = 'fclass.shp'

def __init__(self):
    """Define the tool (tool name is the name of the class)."""
    self.label = "Custom Tool"
    self.description = '''
    Automatization script
    self.canRunInBackground = False

def getParameterInfo(self):
    """Define parameter definitions"""
    params = [
        #Only parameter is a multivalued workspace
            'Geodatabase(s) containing the data',
    return params

def isLicensed(self):
    """Set whether tool is licensed to execute."""
    return True
    def updateParameters(self, parameters):
        """Modify the values and properties of parameters before internal
        validation is performed.  This method is called whenever a parameter
        has been changed."""
        gdbs = parameters[0].valueAsText.split(';')
        for gdb in gdbs:
            arcpy.env.workspace = gdb
            #If the expected class does not exists
            if not arcpy.Exists(diretiz_class):
                #This will not work :
                return parameters[0].setErrorMessage('{0} is not present in the {1} workspace'.format(expected_class,gdb))

    def updateMessages(self, parameters):
        """Modify the messages created by internal validation for each tool
        parameter.  This method is called after internal validation."""

    def execute(self, parameters, messages):
        """The source code of the tool."""
  • Do you want to raise an exception? Read stackoverflow.com/questions/2052390/… about throwing a custom exception. – Michael Stimson Jun 26 '17 at 20:50
  • @MichaelMiles-Stimson no need to kill the script, just want the setErrorMessage to actually work... – Mojimi Jun 26 '17 at 20:54
  • An exception doesn't stop execution altogether, to do that you would sys.exit(ReturnCode) where ReturnCode is negative by convention for an error message and positive for successful execution. Raising an exception is like calling return() and only halts the current block provided that you call your sub in a try/except block, if there's no try/except block an exception will be caught by the next highest level which will halt execution totally and give an error message. – Michael Stimson Jun 26 '17 at 21:04
  • @MichaelMiles-Stimson I understand, but the error won't be applied to the specific parameter, I'm just trying to learn how the Python Toolbox works :), because I also want to add some warnings. But if you're saying raising an error is better, then sure – Mojimi Jun 26 '17 at 21:06
  • Have you tried arcpy.AddError()? resources.arcgis.com/en/help/main/10.2/index.html#//… . You should try to do as much error handling within your script as possible; you can't anticipate every contingency but you should think about the common ones.. if there's something wrong with the arcpy tools or python script they will raise exceptions with error messages which is kind of handy to try to work out whether a script is bailing on arcpy objects or python errors. As python is a scripting (interpretative) language all sorts of errors can exist at the time of execution – Michael Stimson Jun 26 '17 at 21:13

setErrorMessage should be called from updateMessages, not from updateParameters. Check out example 3 on http://pro.arcgis.com/en/pro-app/arcpy/classes/parameter.htm

I don't have your data to test on, but you can try with something like the below on a simple string parameter field. It should give either an error or a warning, so you can verify that something happens, before adding the more complex checks.

def updateMessages(self):
  """Modify the messages created by internal validation for each tool
  parameter.  This method is called after internal validation."""
  if len(str(self.params[0].value)) > 5:
      self.params[0].setErrorMessage("Value is long")
      self.params[0].setWarningMessage("Value is not so long...")
| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.