Gestion des erreurs avec Python
Des erreurs se produisent. Ecrire des scripts qui guettent 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 de nombreuses raisons qui ne sont pas spécifiquement liées à un outil de géotraitement, qui 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 erreur système, ou une exception. Python permet d'écrire une routine exécutée automatiquement chaque fois qu'une erreur système est générée. Dans cette routine de gestion des erreurs, vous pouvez récupérer le message d'erreur à partir d'ArcPy et réagir 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.
Les messages d'erreur des outils de géotraitement sont accompagnés d'un code à six chiffres. Ces codes d'identification sont documentés pour fournir des informations supplémentaires sur leur cause et la manière dont ils peuvent être gérés.
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 simple est la façon la plus facile de gérer les erreurs.
Dans le code ci-dessous, l'outil Zone tampon échoue car le paramètre Distance 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 la Zone tampon renvoie une erreur.
import arcpy
try:
# Execute the Buffer tool
#
arcpy.Buffer_analysis("c:/transport/roads.shp", "c:/transport/roads_buffer.shp")
except Exception as e:
print e.message
# 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.message)
L'instruction try comporte une clause facultative finally utile pour les tâches devant systématiquement être exécutées, qu'une exception se produise ou pas. Dans l'exemple suivant, l'Extension ArcGIS 3D Analyst 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
from arcpy import env
try:
if arcpy.CheckExtension("3D") == "Available":
arcpy.CheckOutExtension("3D")
else:
# Raise a custom exception
#
raise LicenseError
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:
print arcpy.GetMessages(2)
finally:
# Check in the 3D Analyst extension
#
arcpy.CheckInExtension("3D")
raise, instruction
L'exemple précédent concerne le traitement d'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 à ce propos. 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
arcpy.env.overwriteOutput = 1
fc = arcpy.GetParameterAsText(0)
try:
# Check that the input has features
#
result = arcpy.GetCount_management(fc)
if int(result.getOutput(0)) > 0:
arcpy.FeatureToPolygon_management(fc, os.path.dirname(fc) + os.sep + "out_poly.shp")
else:
# Raise custom exception
#
raise NoFeatures(result)
except NoFeatures:
# The input has no features
#
print fc + " has no features."
except:
# By default any other errors will be caught here
#
print arcpy.GetMessages(2)
Classe ExecuteError
Lorsqu'un outil de géotraitement échoue il lève une classe d'exception ExecuteError. Vous pouvez par conséquent diviser les erreurs en deux groupes : les erreurs de géotraitement (qui lèvent l'exception ExecuteError) et les autres. Vous pouvez ensuite gérer les erreurs de manière différente, comme indiqué dans le code ci-dessous :
import arcpy
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:
arcpy.AddError("Non-tool error occurred")
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/PythonWin
#
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 + "\n"
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 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 avait été utilisé, mais qu'un type d'erreur différent s'était produit, la seconde instruction except aurait été 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 ("une chaîne de texte") |
|
Obtention de messages d'erreur à partir d'un objet Result
Ci-dessous figure une brève présentation de l'objet de résultat :
result = arcpy.GetCount_management("c:/data/rivers.shp")
Si l'appel de GetCount déclenche une exception, l'objet de résultat est nul. Cela signifie que vous ne pouvez pas récupérer de messages d'erreur de l'objet de résultat.
import arcpy
try:
result = arcpy.GetCount_management("c:/data/rivers.shp")
# Return GEOPROCESSING specific errors
# (this method is INCORRECT!)
except:
arcpy.AddError(result.getMessages(2))
Le code ci-dessus échoue et affiche le message "nom 'résultat' n'est pas défini". Ceci est dû au fait que l'objet de résultat n'a pas pu être créé en raison de l'échec de l'outil. Comme aucun objet de résultat n'est créé, une erreur Python est déclenchée lors de la tentative d'utilisation de la méthode getMessages.
Un objet de résultat créé en appelant un service de géotraitement ArcGIS for Server est créé même en cas d'échec d'outil. La création d'un objet de résultat n'échoue que lorsqu'un outil est exécuté localement et déclenche une erreur. Pour plus d'informations sur l'utilisation d'un objet de résultat, reportez-vous à la rubrique Obtention de résultats à partir d'un outil de géotraitement.