Search code examples
pythonarcgisarcpy

Error handling advice needed for Python arcpy script


I could use some advice on how to handle errors in my Python script. From what I have been able to gather from reading all of the Python error handling posts on this site, is that you cannot simply bypass an error within a for loop with a try except continue statement. Instead, you have to handle each error directly. This is where I am having problems tying it all together. I have attached the error message that occured in the middle of a for loop. Additionally, I have attached my script which moves through the following workflow:

  1. place a polygon around the raster
  2. place a point on the mean center of the polygon
  3. use the point to identify a specific county associated with its corresponding raster
  4. clip the raster based on the selected county polygon

How do I incorporate information from the error message into a try except continue statement, so that the script can move to the next raster in the list rather than stopping in the middle of processing?

# Import arcpy module
import arcpy
from arcpy import env
from arcpy.sa import *
arcpy.CheckOutExtension("3D")

# Set Over write
arcpy.env.overwriteOutput = 1

# Set the workspace
env.workspace = r"Z:\temp.gdb"
outworkspace = r"Z:\location2\temp2.gdb"

# Local variables:
counties = r"Z:\temp.gdb\boundaries\Counties"
counties_lyr = arcpy.MakeFeatureLayer_management(counties,"counties_lyr")

# Get the list of rasters to process
raster_list = arcpy.ListRasters("*_clp")
print raster_list

for raster in raster_list:
    # Define name and location for output raster
    name = outworkspace + "\\" + str(raster)

    # Process: Raster Domain
    arcpy.RasterDomain_3d(raster, "in_memory/temp", "POLYGON")

    # Process: Central Feature
    arcpy.MeanCenter_stats("in_memory/temp", "in_memory/temp1")

    # Process: Select Layer By Location
    arcpy.SelectLayerByLocation_management(counties_lyr, "intersect", "in_memory/temp1", "", "NEW_SELECTION")

    # Clip Raster
    arcpy.Clip_management(raster, "#", name,counties_lyr, "#", "ClippingGeometry")

    # Delete in_memory
    arcpy.Delete_management("in_memory")

    print "processing " + raster + " complete..."

print "All processing is now finished"

enter image description here


Solution

  • Is this what you need? It will print out the traceback if anything goes wrong with any individual raster in the for loop, and then move on to the next one.

    import traceback
    
    # Import arcpy module
    import arcpy
    from arcpy import env
    from arcpy.sa import *
    arcpy.CheckOutExtension("3D")
    
    # Set Over write
    arcpy.env.overwriteOutput = 1
    
    # Set the workspace
    env.workspace = r"Z:\temp.gdb"
    outworkspace = r"Z:\location2\temp2.gdb"
    
    # Local variables:
    counties = r"Z:\temp.gdb\boundaries\Counties"
    counties_lyr = arcpy.MakeFeatureLayer_management(counties,"counties_lyr")
    
    # Get the list of rasters to process
    raster_list = arcpy.ListRasters("*_clp")
    print raster_list
    
    for raster in raster_list:
        try:
            # Define name and location for output raster
            name = outworkspace + "\\" + str(raster)
    
            # Process: Raster Domain
            arcpy.RasterDomain_3d(raster, "in_memory/temp", "POLYGON")
    
            # Process: Central Feature
            arcpy.MeanCenter_stats("in_memory/temp", "in_memory/temp1")
    
            # Process: Select Layer By Location
            arcpy.SelectLayerByLocation_management(counties_lyr, "intersect", "in_memory/temp1", "", "NEW_SELECTION")
    
            # Clip Raster
            arcpy.Clip_management(raster, "#", name,counties_lyr, "#", "ClippingGeometry")
    
            # Delete in_memory
            arcpy.Delete_management("in_memory")
    
            print "processing " + raster + " complete..."
    
        except:
            print "Something went wrong handling " + str(raster) + ". Here's a traceback:"
            traceback.print_exc()
            continue
    
    print "All processing is now finished"
    

    This is a lazy programmer's implementation, wrapping the entire contents of the for loop in a try... except... block that will catch exceptions of any type anywhere in the block. Depending upon your needs and tastes, you may find it more helpful (or simply more elegant) to catch only the specific error that you're getting in practice, as dm03514 suggested - but I figure that for a little script like this whose output is going to be viewed by a human, it doesn't matter which you do.

    What probably IS important to you, as you specify in the question, is that you see the traceback when an error occurs. That's where traceback.print_exc() comes in. :)