逆引き:エラーの読み方と起動失敗
Traceback、HTTPエラー、起動失敗など、Bot開発で起きるエラーの読み方と切り分けを整理します。
この記事で分かること
- Tracebackの自分のコード位置を見る
- SyntaxError/IndentationErrorを分ける
- NoneType/AttributeError/KeyErrorを読む
- 依存関係とimport失敗を確認する
- 400は入力形式と対象を確認する
- 401/403/404を権限や対象で分ける
コミュニティの相談ログを匿名化・一般化し、エラーの読み方と起動失敗の切り分けとして整理した逆引きです。
Traceback・例外名読み方
Tracebackとstack traceの読み方
最後の一行だけでなく、自分のコードへ戻る位置を確認します。
自分のファイルを探す
Tracebackやstack traceでは、例外名、自分のファイル名、ライブラリ内部へ入る直前、最初に投げられた原因を分けます。最後の一行だけを貼ると原因が見えないことがあります。
実行条件を添える
言語、バージョン、ライブラリ、起動コマンド、直前の変更を一緒に残します。スクリーンショットではなく伏せ字にしたテキストを優先します。
確認ポイント
- 例外名
- 自分のファイル名
- 行番号
- 実行コマンド
参考(公式ドキュメント)
SyntaxError・IndentationError
構文やインデントのエラーを実行前の問題として分けます。
実行前に止まる
SyntaxErrorやIndentationErrorは、処理の途中ではなくコードを読む段階で止まることがあります。Botの権限やIntentでは直りません。
位置を確認する
エラー表示の行だけでなく、その直前の括弧、クォート、インデント、全角文字、コピー時の欠落を確認します。
確認ポイント
- 該当行
- 直前の行
- 括弧/クォート
- インデント
参考(公式ドキュメント)
再現条件を小さくする
本番だけ、特定チャンネルだけ、特定コマンドだけを分けます。
最小コードへ戻す
機能を足した後に壊れた場合は、最小Bot、最小コマンド、単一チャンネルで再現するか確認します。
直前の変更を見る
依存更新、Intent変更、権限変更、環境変数変更、デプロイ環境変更を時系列で確認します。
確認ポイント
- 直前の変更を書き出す
- ローカルと本番を分ける
- 対象サーバー/チャンネルを限定する
TypeError・NoneType・AttributeError
値の型や存在しない属性を確認します。
値を決めつけない
NoneType、TypeError、AttributeErrorは、期待したobjectが取れていない、型が違う、古い記事のAPI名を使っているなどで起きます。対象をprint/logで確認します。
ライブラリ版を見る
discord.pyやdiscord.jsのメジャーバージョン差で属性名や戻り値が変わることがあります。古い記事のコードを現在の公式情報で読み替えます。
確認ポイント
- 値の型
- Noneかどうか
- 属性名
- ライブラリ版
参考(公式ドキュメント)
ModuleNotFound・依存関係
importやpackage installの失敗を環境ごとに分けます。
実行環境を見る
ローカルで入れたpackageが本番環境に入っていない、requirements/package.jsonが更新されていない、起動コマンドの仮想環境が違う、という失敗を分けます。
インストールログを見る
ModuleNotFoundErrorやnpm install失敗は、実行時ログだけでなくbuild/installログも確認します。音声系やネイティブ依存はOS依存も分けます。
確認ポイント
- requirements/package.json
- build log
- runtime log
- 実行環境
参考(公式ドキュメント)
- https://docs.python.org/3/library/exceptions.html
- https://docs.npmjs.com/cli/v10/commands/npm-install
Discord API HTTPエラー・起動失敗
400 Bad Requestと入力形式
Bad Requestの原因をpayload、対象、形式に分けます。
payloadを見る
400系は、送ったJSON、文字数、Embedの形式、対象ID、添付/Embedの組み合わせなど入力形式が原因のことがあります。権限だけを増やしても直らない場合があります。
対象を確認する
存在しないチャンネル、削除済みメッセージ、古いInteraction、形式が合わないIDなどを分け、管理ログには送信直前の要約を残します。
確認ポイント
- HTTP status
- endpoint
- 対象ID
- payload要約
参考(公式ドキュメント)
401・403・404の切り分け
認証、権限、存在しない対象を混同しない確認です。
意味を分ける
401は認証、403は権限、404は対象が存在しない/見えない可能性など、見る場所が違います。Token、Bot導入、ロール、チャンネル上書き、対象IDを順に確認します。
利用者向けと管理者向けを分ける
利用者には短く返し、管理者向けログにはstatus、対象ID、必要権限、現在の権限、例外名を残します。
確認ポイント
- 401/403/404
- 必要権限
- 対象ID
- Bot導入
参考(公式ドキュメント)
- https://docs.discord.com/developers/topics/opcodes-and-status-codes
- https://docs.discord.com/developers/topics/permissions
429 Rate Limitと再試行
連投や一括処理で止まる時の確認です。
429を例外扱いしすぎない
Rate Limitは再試行や待機が必要な制限です。一括送信、全guild処理、全member処理などを小分けにし、残り時間や対象数をログに残します。
失敗を局所化する
全体を止めるのか、対象ごとにスキップするのか、再試行するのかを決めます。利用者には処理中/保留を返し、管理ログに詳細を残します。
確認ポイント
- 対象数
- 再試行可否
- 待機時間
- 失敗対象
参考(公式ドキュメント)
起動・イベント・handler・返信
Botが反応しない時の到達点を分けます。
段階を分ける
起動していない、Gateway接続していない、イベントが届かない、handlerに入っていない、返信だけ失敗する、のどこかをログで分けます。
握りつぶさない
try/catch、on_error、on_command_errorで例外を消すと、反応しないように見えます。readyログ、イベント到達ログ、handler先頭ログ、返信前後ログを残します。
確認ポイント
- readyログ
- event到達
- handler先頭
- 返信前後
- 例外全文
参考(公式ドキュメント)
一次情報(公式ドキュメント)
- Python traceback documentation
- Python built-in exceptions
- npm install documentation
- Discord Developer Documentation: Status Codes
- Discord Developer Documentation: Rate Limits
- Discord Developer Documentation: Gateway