Los errores ocurren. Escribir scripts que esperen y gestionen errores puede ahorrarle tiempo y frustración. Cuando una herramienta devuelve un mensaje de error, ArcPy genera un error de sistema o una excepción. En Python, puede proporcionar una variedad de estructuras y métodos que pueden manejar excepciones. Por supuesto, un script puede generar errores por razones que no están relacionadas con una herramienta de geoprocesamiento. Estos errores también se deben detectar y tratar de un modo adecuado. Las siguientes secciones ofrecen algunas técnicas que presentan los conceptos básicos del manejo de excepciones de Python.
Cuando una herramienta escribe un mensaje de error, ArcPy genera una excepción arcpy.ExecuteError. Python permite escribir una rutina que se ejecuta automáticamente cuando se genera un error del sistema. En esta rutina de tratamiento de los errores, recupere el mensaje de error de ArcPy y actúe en consecuencia. Si un script no tiene una rutina de manejo de errores, falla inmediatamente, lo que disminuye su solidez. Utilice las rutinas de manejo de errores y mejore la utilidad de un script.
declaración try-except
Se puede utilizar una instrucción try-except para envolver programas completos o solo partes determinadas del código para interceptar e identificar errores. Si se produce un error dentro de la instrucción try, se emite una excepción y luego se ejecuta el código de la instrucción except. Utilizar una instrucción except básica es la forma más básica de tratar los errores.
En el siguiente código, Zona de influencia falla porque no se ha proporcionado el argumento buffer_distance_or_field requerido. En lugar de fallar sin explicación, la instrucción except se utiliza para capturar el error. A continuación, se recupera e imprime el mensaje de error que genera la Zona de influencia. Tenga en cuenta que el bloque except solo se ejecuta si Zona de influencia devuelve un error.
import arcpy
import sys
try:
# Execute the Buffer tool
arcpy.Buffer_analysis("c:/transport/roads.shp", "c:/transport/roads_buffer.shp")
except Exception:
e = sys.exc_info()[1]
print(e.args[0])
# If using this code within a script tool, AddError can be used to return messages
# back to a script tool. If not, AddError will have no effect.
arcpy.AddError(e.args[0])
La instrucción try tiene una cláusula finally opcional que se puede utilizar para las tareas que siempre se deben ejecutar, independientemente de si se ha producido una excepción o no. En el siguiente ejemplo, se realiza un check-in de ArcGIS 3D Analyst extension en la cláusula finally, lo que garantiza que siempre se aplicará un check-in a la extensión.
class LicenseError(Exception):
pass
import arcpy
try:
if arcpy.CheckExtension("3D") == "Available":
arcpy.CheckOutExtension("3D")
else:
# Raise a custom exception
raise LicenseError
arcpy.env.workspace = "D:/GrosMorne"
arcpy.HillShade_3d("WesternBrook", "westbrook_hill", 300)
arcpy.Aspect_3d("WesternBrook", "westbrook_aspect")
except LicenseError:
print "3D Analyst license is unavailable"
except arcpy.ExecuteError:
print(arcpy.GetMessages(2))
finally:
# Check in the 3D Analyst extension
arcpy.CheckInExtension("3D")
Instrucción raise
El ejemplo anterior trata una excepción que se ha producido en el código. En algunos casos, puede ser necesario crear excepciones personalizadas. Para este propósito, se puede utilizar una instrucción raise. En el siguiente código, se utiliza una instrucción raise cuando se identifica una clase de entidad de entrada sin entidades. Esto no es estrictamente un error sino una condición de que el código se puede utilizar para evitar esta situación.
class NoFeatures(Exception):
pass
import arcpy
import os
import sys
arcpy.env.overwriteOutput = True
fc = arcpy.GetParameterAsText(0)
try:
# Check that the input has features
result = arcpy.GetCount_management(fc)
if int(result[0]) > 0:
arcpy.FeatureToPolygon_management(
fc, os.path.join(os.path.dirname(fc), 'out_poly.shp'))
else:
# Raise custom exception
raise NoFeatures(result)
except NoFeatures:
# The input has no features
print('{} has no features'.format(fc))
except:
# By default any other errors will be caught here
e = sys.exc_info()[1]
print(e.args[0])
Clase ExecuteError
Cuando una herramienta de geoprocesamiento falla, genera una clase de excepción arcpy.ExecuteError, lo que significa que puede dividir los errores en diferentes grupos, errores de geoprocesamiento (los que generan la excepción arcpy.ExecuteError) y otros tipos de excepción. Después puede manejar los errores de formas diferentes, como se demuestra en el siguiente código:
import arcpy
import sys
try:
result = arcpy.GetCount_management("C:/invalid.shp")
# Return geoprocessing specific errors
except arcpy.ExecuteError:
arcpy.AddError(arcpy.GetMessages(2))
# Return any other type of error
except:
# By default any other errors will be caught here
e = sys.exc_info()[1]
print(e.args[0])
traceback
En scripts más grandes y complejos, puede resultar difícil determinar la ubicación exacta de un error. Los módulos sys y traceback de Python se pueden utilizar juntos para aislar la ubicación exacta y la causa del error, identificar la causa de un error con más precisión y ahorrar tiempo de depuración.
# Import the required modules
#
import arcpy
import sys
import traceback
arcpy.env.workspace = "C:/Data/myData.gdb"
try:
arcpy.CreateSpatialReference_management()
#--------------------------
# Your code goes here
#
# See the table below for examples
#--------------------------
except arcpy.ExecuteError:
# Get the tool error messages
msgs = arcpy.GetMessages(2)
# Return tool error messages for use with a script tool
arcpy.AddError(msgs)
# Print tool error messages for use in Python
print(msgs)
except:
# Get the traceback object
tb = sys.exc_info()[2]
tbinfo = traceback.format_tb(tb)[0]
# Concatenate information together concerning the error into a message string
pymsg = "PYTHON ERRORS:\nTraceback info:\n" + tbinfo + "\nError Info:\n" + str(sys.exc_info()[1])
msgs = "ArcPy ERRORS:\n" + arcpy.GetMessages(2) + "\n"
# Return Python error messages for use in script tool or Python window
arcpy.AddError(pymsg)
arcpy.AddError(msgs)
# Print Python error messages for use in Python / Python window
print(pymsg)
print(msgs)
Si se utilizara el código anterior y se produjera un error de la herramienta de geoprocesamiento, como una entrada no válida, se generaría arcpy.ExecuteError y se utilizaría la primera instrucción except. Esta instrucción imprimirá los mensajes de error mediante la función GetMessages. Si se utilizara el mismo código, pero se produjera un tipo diferente de error, se utilizaría la segunda instrucción except. En lugar de imprimir mensajes de geoprocesamiento, obtiene un objeto traceback e imprime los mensajes de error correspondientes del sistema.
La siguiente tabla muestra los errores esperados que son el resultado de tres líneas diferentes de códigos que se pueden sustituir en el código anterior. El primero es un error de la herramienta de geoprocesamiento, que imprime la información de traceback y los mensajes de error de geoprocesamiento. Los ejemplos segundo y tercero no se determinan de manera específica y solamente se imprime la información de traceback.
Su código | Error resultante |
---|---|
arcpy.GetCount_management("") |
|
x = "a" + 1 |
|
float("a text string") |
|
Obtener mensajes de error desde un objeto de resultados
A continuación, se muestra un breve análisis sobre el objeto Result:
result = arcpy.GetCount_management("c:/data/rivers.shp")
Si la llamada a GetCount_management genera una excepción, el objeto Result no se crea. Significa que no es posible recuperar mensajes de error desde el objeto Result.
import arcpy
try:
result = arcpy.GetCount_management("c:/data/rivers.shp")
# Return Geoprocessing specific errors
# (this method is incorrect!)
except arcpy.ExecuteError:
arcpy.AddError(result.getMessages(2))
El código anterior falla con el mensaje name 'result' is not defined. Se debe a que no se pudo crear el objeto Result por el error de la herramienta. Como no se ha creado el objeto Result, se muestra un error de Python cuando se intenta utilizar el método getMessages.