3秒でわかる
エラーが起きるまでに通った関数の呼び出し経路を並べた記録。どのファイルの何行目で落ちたかが分かり、原因を絞り込む最初の手がかりになります。
もう少し詳しく
どういうものか
トレースバックは、Python が例外で止まったときに表示する、呼び出しの道のりです。どのファイルの何行目から何行目へ入り、最後にどこで落ちたのかが上から順に並びます。
Traceback (most recent call last)
File "app.py", line 21, in <module>
main()
File "app.py", line 15, in main
total = calc(items)
File "app.py", line 8, in calc
return sum(i["price"] for i in items)
KeyError: 'price'なぜ必要か
エラーの表示は、単に「失敗した」ではなく「どこから来て、どこで失敗したか」を教えています。一番下の行が例外の種類と内容、その 1 つ上が実際に落ちたコードです。ここだけ先に読めば、調べる範囲が数行に絞れます。
具体例
読む順番は下からです。上の例なら、まず KeyError: 'price' を見て「price というキーが無い辞書があった」と分かります。次に line 8, in calc を見て、items の中に price を持たない要素が混ざっていると当たりを付けます。
自分のコードでトレースバックを記録に残すこともできます。
import logging
import traceback
try:
run()
except Exception:
logging.error("<a href="/glossary/process-flow" class="text-primary font-medium underline underline-offset-2 hover:text-primary-dark">処理</a>に失敗しました\n%s", traceback.format_exc())print(e) だけだと例外のメッセージしか残らず、どこで落ちたかが消えます。format_exc() なら経路ごと文字列で取れます。
つまずきやすいところ
一番上の行を読んでしまう人が多いです。上にあるのは最初の呼び出し元で、原因ではありません。
ライブラリの中の行が延々と並ぶこともあります。その場合も、自分が書いたファイル名が出ている一番下の行が調べる場所です。ライブラリ内部の行から読み始めると迷います。
例外を握りつぶすコードも厄介です。
try:
run()
except Exception:
pass # 何も起きていないように見えて、原因が消えるこれを書くと、トレースバックそのものが残らなくなります。
覚え方
トレースバックは下から読みます。最下段が「何が起きたか」、その 1 つ上が「どこで起きたか」です。この 2 行だけで、調べる範囲はほぼ決まります。