Des erreurs se produisent. Ecrire des scripts qui détectent et gèrent les erreurs peut vous permettre de gagner beaucoup de temps. Lorsqu’un outil renvoie un message d’erreur, ArcPy génère une erreur système ou une exception. Dans Python, vous pouvez fournir différentes structures et méthodes pour gérer les exceptions. Bien entendu, un script peut échouer pour d’autres raisons qui ne sont pas liées à un outil de géotraitement. Ces raisons doivent également être identifiées et gérées de manière appropriée. Les sections suivantes fournissent quelques techniques qui vous présentent les concepts de base de la gestion des exceptions Python.
Lorsqu’un outil écrit un message d’erreur, ArcPy génère une exception arcpy.ExecuteError. Python permet d’écrire une routine qui s’exécute automatiquement lorsqu’une erreur système est générée. Dans cette routine de gestion des erreurs, récupérez le message d’erreur à partir d’ArcPy et réagissez en conséquence. Si un script ne comporte pas de routine de gestion des erreurs, il échoue aussitôt, ce qui réduit son efficacité. Utilisez des routines de gestion d’erreur pour gérer les erreurs et améliorer la fonctionnalité d’un script.
instruction try/except
Une instruction try-except permet de passer en revue des programmes entiers ou des portions particulières de code afin d’identifier les erreurs. Si une erreur se produit au sein de l’instruction try, une exception est générée et le code placé sous l’instruction except est exécuté. L’utilisation d’une instruction except de base est la façon la plus facile de gérer les erreurs.
Dans le code ci-dessous, l’outil Zone tampon échoue car l’argument buffer_distance_or_field requis n’a pas été spécifié Au lieu d’échouer sans explication, l’instruction except permet d’identifier l’erreur, puis de récupérer et d’imprimer le message d’erreur généré par l’outil Zone tampon. Notez que le bloc except est exécuté uniquement si l’outil Zone tampon renvoie une erreur.
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])
L’instruction try comporte une clause finally facultative utile pour les tâches devant systématiquement être exécutées, qu’une exception se produise ou pas. Dans l’exemple suivant, l’ArcGIS 3D Analyst extension est réinsérée selon une clause finally, ce qui signifie qu’elle est toujours réinsérée.
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")
Instruction raise
L’exemple précédent concerne une exception survenue dans le code. Dans certains cas, vous pouvez être amené à créer des exceptions personnalisées. Une instruction raise peut être utilisée à cette fin. Dans le code suivant, une instruction raise est utilisée quand une classe d’entités en entrée est identifiée comme n’ayant aucune entité. Il ne s’agit pas strictement d’une erreur mais d’une condition contre laquelle le code peut intervenir.
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])
Classe ExecuteError
Lorsqu’un outil de géotraitement échoue également, il lève une classe d’exception arcpy.ExecuteError, ce qui signifie que vous pouvez diviser les erreurs en différents groupes : les erreurs de géotraitement (qui lèvent l’exception arcpy.ExecuteError) et d’autres types d’exceptions. Vous pouvez ensuite gérer les erreurs de manière différente, comme indiqué dans le code ci-dessous :
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
Dans les scripts plus importants et plus complexes, il peut être difficile de déterminer l’emplacement précis d’une erreur. Les modules sys et traceback de Python permettent d’isoler l’emplacement exact et la cause d’une erreur, en identifiant plus précisément la cause de l’erreur et en vous permettant d’économiser un temps précieux pour le débogage.
# 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 le code ci-dessus est utilisé et qu’une erreur d’outil de géotraitement se produit, une entrée incorrecte par exemple, l’erreur arcpy.ExecuteError est levée et la première instruction except est utilisée. Cette instruction imprime les messages d’erreur à l’aide de la fonction GetMessages. Si le même code était utilisé, mais qu’un type d’erreur différent se produisait, la seconde instruction except serait utilisée. Au lieu d’imprimer des messages de géotraitement, elle obtient un objet traceback et imprime les messages d’erreur système appropriés.
Le tableau suivant montre les erreurs attendues qui proviennent de trois lignes de codes différentes qui pourraient être substituées dans le code ci-dessus. La première est une erreur d’outil de géotraitement, qui imprime les informations traceback et les messages d’erreur de géotraitement. Le deuxième et le troisième exemple ne sont pas spécifiquement identifiés et impriment uniquement les informations traceback.
Votre code | Erreur |
---|---|
arcpy.GetCount_management("") |
|
x = "a" + 1 |
|
float("a text string") |
|
Obtention de messages d’erreur à partir d’un objet Result
Ci-dessous figure une brève présentation de l’objet Result :
result = arcpy.GetCount_management("c:/data/rivers.shp")
Si l’appel de GetCount_management déclenche une exception, l’objet Result n’est pas créé. Cela signifie que vous ne pouvez pas récupérer de messages d’erreur de l’objet 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))
Le code ci-dessus échoue avec le message name 'result' is not defined. Ceci est dû au fait que l’objet Result n’a pas pu être créé en raison de l’échec de l’outil. Comme aucun objet Result n’est créé, une erreur Python est déclenchée lors de la tentative d’utilisation de la méthode getMessages.