エラーはどうしても起こるものです。エラーを予期して処理するスクリプトを作成することで、時間を節約でき、フラストレーションが少なくなります。ツールがエラー メッセージを返すと、ArcPy はシステム エラーまたは例外を生成します。Python では、例外を処理できるさまざまな構造体とメソッドをユーザーが提供することができます。もちろん、スクリプトはジオプロセシング ツールと関係ないその他の理由で失敗する可能性もあります。それらも認識され、適切な方法で処理される必要があります。次に、Python による例外処理の基本例を示す手法をいくつか説明します。
ツールからエラー メッセージが出力されると、ArcPy は arcpy.ExecuteError 例外を生成します。Python では、システム エラーが生成されると自動的に実行されるルーチンを作成できます。このエラー処理ルーチン内で、ArcPy からのエラー メッセージを読み取り、状況に応じて対処します。スクリプトにエラー処理ルーチンが含まれていない場合、スクリプトは直ちに失敗してしまうので、堅牢性が低下します。エラー処理ルーチンを使用して、これらのエラーに対処し、スクリプトのユーザービリティを向上させてください。
try-except ステートメント
try-except ステートメントを使用して、プログラム全体またはコードの特定部分のみをラップし、エラーをトラップして識別できます。try ステートメント内でエラーが発生すると例外が起こり、except ステートメント以下のコードが実行されます。基本的な except ステートメントの使用は、エラー処理の最も基本的な形です。
次に示すコードでは、必要な buffer_distance_or_field 引数が指定されていないために [バッファー (Buffer)] が失敗します。説明を表示せずに失敗する代わりに、except ステートメントを使用してエラーをトラップし、[バッファー (Buffer)] から生成されたエラー メッセージを取得して出力しています。except ブロックは、[バッファー (Buffer)] がエラーを返した場合のみ実行されることに注意してください。
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])
try ステートメントでは、オプションで finally 節を使用でき、これは、例外が発生するかどうかに関係なく常に実行される必要のあるタスクに使用できます。次の例では、ArcGIS 3D Analyst が finally 句でチェックインされているため、このエクステンションは常にチェックインされます。
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 ステートメント
前の例は、コード内で発生する例外を処理しています。場合によっては、カスタムの例外を作成する必要があります。これには raise ステートメントを使用できます。次のコードでは、入力フィーチャクラスにフィーチャが含まれていないと判定されたときに raise ステートメントが使用されます。これは厳密にはエラーではなく条件であり、このコードを使用すれば失敗を防ぐことができます。
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 クラス
ジオプロセシング ツールでエラーが発生すると、arcpy.ExecuteError 例外クラスが渡されます。これは、エラーをさまざまなグループ、ジオプロセシング エラー (arcpy.ExecuteError 例外を渡すエラー)、およびその他の例外タイプに分類できることを意味しています。これにより、次のコード例に示されているように、異なる方法でエラーを処理できます。
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
大規模で複雑なスクリプトでは、エラーが発生した正確な位置を判別することが難しい場合があります。Python の sys モジュールと traceback モジュールを組み合わせて使用すれば、エラーの厳密な位置と原因を特定して、エラーの原因をより正確に識別できるので、貴重なデバッグ時間を節約できます。
# 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)
print(msgs)
上記のコードの使用中に、ジオプロセシング ツールでエラーが発生すると (入力が無効など)、arcpy.ExecuteError が生成され、最初の except ステートメントが使用されます。このステートメントは、GetMessages 関数を使用してエラー メッセージを出力します。同じコードを使用して別のタイプのエラーが発生した場合は、2 番目の except ステートメントが使用されます。ジオプロセシング メッセージを出力する代わりに、traceback オブジェクトを取得して、該当するシステム エラー メッセージを出力します。
次の表は、前記のコードに置き換えて 3 つの異なるコード行を挿入した場合に発生すると予測されるエラーを示しています。1 つ目はジオプロセシング ツールのエラーであり、traceback 情報とジオプロセシング エラー メッセージが出力されます。2 つ目と 3 つ目の例では、エラーは具体的には捕捉されず、traceback 情報のみが出力されます。
コード | 発生するエラー情報 |
---|---|
arcpy.GetCount_management("") |
|
x = "a" + 1 |
|
float("a text string") |
|
Result オブジェクトからのエラー メッセージの取得
Result オブジェクトについての概要を次に示します。
result = arcpy.GetCount_management("c:/data/rivers.shp")
GetCount_management の呼び出しで例外が発生した場合、Result オブジェクトは作成されません。つまり、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))
上記のコードは、name 'result' is not defined というメッセージを出力して失敗します。この理由は、ツールが失敗したため Result オブジェクトを作成できなかったからです。Result オブジェクトが作成されないため、getMessages メソッドを試行すると Python エラーが生成されます。