Fehlerbehandlung mit Python

Fehler sind nicht immer zu vermeiden. Wenn Sie Skripte erstellen, die auf Fehler vorbereitet sind und darauf reagieren können, sparen Sie sich Zeit und Nerven. Wenn ein Werkzeug eine Fehlermeldung zurückgibt, erzeugt ArcPy einen Systemfehler bzw. eine Ausnahme. In Python können Sie eine Reihe von Strukturen und Methoden bereitstellen, mit denen Ausnahmen verarbeitet werden. Skripte können natürlich auch aus anderen Gründen, die nichts mit dem Geoverarbeitungswerkzeug zu tun haben, fehlschlagen. Auch diese Fehler müssen abgefangen und entsprechend behandelt werden. In den folgenden Abschnitten werden einige Vorgehensweisen erläutert, die Ihnen die Grundlagen der Fehlerbehandlung in Python vorstellen.

Wenn ein Werkzeug eine Fehlermeldung schreibt, erzeugt ArcPy eine arcpy.ExecuteError-Ausnahme. Mit Python können Sie eine Routine schreiben, die bei jedem Systemfehler automatisch ausgeführt wird. In dieser Fehlerverarbeitungsroutine rufen Sie die Fehlermeldung aus ArcPy ab und reagieren entsprechend darauf. Wenn ein Skript über keine Fehlerbehandlungsroutine verfügt, schlägt seine Ausführung sofort fehl. Dies bedeutet natürlich, dass es weniger robust ist. Verwenden Sie daher Fehlerbehandlungsroutinen, um Fehler zu erkennen und die Verwendbarkeit von Skripten zu verbessern.

Fehlermeldungen der Geoverarbeitungswerkzeuge gehen mit einem sechsstelligen Code einher. In der Dokumentation zu den ID-Codes finden Sie weitere Informationen zu den Ursachen und zur Fehlerbehebung.

try-/except-Anweisung

In einer try-except-Anweisung können ganze Programme oder bestimmte Codeabschnitte eingeschlossen werden, um Fehler abzufangen und zu identifizieren. Wenn innerhalb der try-Anweisung ein Fehler auftritt, wird eine Ausnahme ausgelöst, und der Code unter der except-Anweisung wird ausgeführt. Eine einfache except-Anweisung ist die einfachste Form der Fehlerbehandlung.

Im folgenden Code schlägt Puffer fehl, weil das erforderliche buffer_distance_or_field-Argument nicht bereitgestellt wurde. Anstatt ohne Erklärung fehlzuschlagen, wird der Fehler mit der except-Anweisung abgefangen und die von Puffer erzeugte Fehlermeldung wird erfasst und ausgegeben. Beachten Sie, dass der except-Block nur ausgeführt wird, wenn Puffer einen Fehler zurückgibt.

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])

Die try-Anweisung weist eine optionale finally-Klausel auf. Diese kann für Vorgänge verwendet werden, die unabhängig davon, ob ein Fehler aufgetreten ist, immer ausgeführt werden sollen. Im folgenden Beispiel wird die ArcGIS 3D Analyst extension nach einer finally-Klausel wieder eingecheckt. Dadurch wird sichergestellt, dass die Erweiterung stets wieder eingecheckt wird.

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")

raise-Anweisung

Im oben gezeigten Beispiel wird eine Ausnahme erläutert, die im Code aufgetreten ist. In einigen Fällen müssen möglicherweise benutzerdefinierte Ausnahmen erstellt werden. Zu diesem Zweck kann eine raise-Anweisung verwendet werden. Im folgenden Codebeispiel wird eine raise-Anweisung verwendet, wenn eine Eingabe-Feature-Class festgestellt wurde, die keine Features enthält. Im engeren Sinne ist dies kein Fehler. Der Code lässt sich einsetzen, um das Eintreffen dieser Bedingung zu vermeiden.

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])

ExecuteError-Klasse

Wenn ein Geoverarbeitungswerkzeug fehlschlägt, löst es eine arcpy.ExecuteError-Ausnahmeklasse aus. Dies bedeutet, dass Sie Fehler in zwei Gruppen unterteilen können: Geoverarbeitungsfehler (die eine arcpy.ExecuteError-Ausnahme auflösen) und andere Ausnahmetypen. Sie können die Fehler wie im Code unten gezeigt dann jeweils unterschiedlich behandeln:

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

In umfangreichen, komplexen Skripten kann die genaue Position eines Fehlers möglicherweise nur schwer bestimmt werden. Mit den Python-Modulen sys und traceback können die genaue Position und die Ursache des Fehlers ermittelt werden. Dabei wird die Ursache eines Fehlers genauer bestimmt, und es kann wertvolle Zeit bei der Fehlerbehebung gespart werden.

# 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)

Wenn Sie den oben gezeigten Code verwenden und dabei ein Fehler des Geoverarbeitungswerkzeugs (wie etwa eine ungültige Eingabe) auftritt, wird die arcpy.ExecuteError-Ausnahme ausgelöst und die erste except-Anweisung verwendet. Diese Anweisung gibt die Fehlermeldungen dann mithilfe der Funktion GetMessages aus. Tritt bei demselben Code eine andere Art von Fehler auf, wird die zweite except-Anweisung verwendet. In diesem Fall werden nicht die Geoverarbeitungsmeldungen ausgegeben, sondern es wird ein traceback-Objekt abgerufen, und die entsprechenden Systemfehlermeldungen werden gedruckt.

Die folgende Tabelle enthält die erwarteten Fehler aus drei unterschiedlichen Codezeilen, die in den obigen Code eingefügt werden könnten. Der erste Fehler ist ein Fehler des Geoverarbeitungswerkzeugs, bei dem die traceback-Informationen und die Fehlermeldungen der Geoverarbeitung ausgegeben werden. Der zweite und dritte Fehler wird nicht speziell abgefangen und es werden nur die traceback-Informationen ausgegeben.

Ihr CodeFehler

arcpy.GetCount_management("")

PYTHON ERRORS:
Traceback info:
  File "c:\temp\errortest.py", line 10, in <module>
    arcpy.GetCount_management("")

Error Info:
Failed to execute. Parameters are not valid.
ERROR 000735: Input Rows: value is required
Failed to execute (GetCount).

ArcPy ERRORS:
Failed to execute. Parameters are not valid.
ERROR 000735: Input Rows: value is required
Failed to execute (GetCount).

x = "a" + 1

PYTHON ERRORS:
Traceback info:
  File "c:\temp\errortest.py", line 10, in <module>

    x = "a" + 1

Error Info:
cannot concatenate 'str' and 'int' objects

float("a text string")

PYTHON ERRORS:
Traceback info:
  File "c:\temp\errortest.py", line 10, in <module>

    float("a text string")
Error Info:
invalid literal for float(): a text string

Fehlerergebnisse

Abrufen von Fehlermeldungen aus einem Ergebnisobjekt

Eine kurze Anmerkung zum unten dargestellten Result-Objekt:

result = arcpy.GetCount_management("c:/data/rivers.shp")

Wenn der Aufruf zu GetCount_management eine Ausnahme auslöst, wird das Result-Objekt nicht erstellt. Dies bedeutet, dass Sie keine Fehlermeldungen aus dem Result-Objekt abrufen können.

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))

Der oben gezeigte Code schlägt fehl und es wird die Meldung name 'result' is not defined angezeigt. Das liegt daran, dass das Result-Objekt aufgrund des fehlgeschlagenen Werkzeugs nicht erstellt werden konnte. Da das Result-Objekt nicht erstellt wird, wird beim Versuch, die getMessages-Methode zu verwenden, ein Python-Fehler ausgelöst.

Hinweis:

Ein Result-Objekt, das durch den Aufruf eines Geoverarbeitungsservices auf ArcGIS Server erstellt wurde, wird auch erstellt, wenn ein Werkzeug fehlschlägt. Ein Result-Objekt wird nur dann nicht erstellt, wenn ein Werkzeug lokal ausgeführt wird und einen Fehler auslöst. Weitere Informationen zur Verwendung des Ergebnisobjekts finden Sie im Abschnitt Verwenden von Werkzeugen in Python.