简体中文 English 繁體中文 日本語 Русский
本文为静态镜像,内容以交互版为准 在交互式文档中心打开 →

モジュールトラブルシューティングガイド

モジュールが「反応しない」場合、症状に応じて3つの問題に分類され、それぞれに該当するフレームワーク診断ツール(RFC EPRFC-2026-001 方向五)があります。

症状 診断ツール 定位のレベル
モジュールがロードされない ErisPulse.runtime.explain_module(name) 登録とロードのチェーン
イベントが反応しない ErisPulse.runtime.explain_event(event) ディスパッチのエントリポイントの確認
コマンドが発動しない ディスパッチの意思決定チェーン(テスト側の DispatchTrace / フレームワーク内蔵の trace) コマンドの判定チェーン

2つの診断関数はいずれも読み取り専用操作であり、状態を一切変更せず、いつでも呼び出すことができます。返り値は機械可読な dict で、format_report() と組み合わせることで人間が読めるテキストにレンダリングされます。

シナリオ1:モジュールがロードされていない

from ErisPulse.runtime import explain_module, format_report

report = explain_module("MyModule")
print(format_report(report))

explain_module() は、順次チェックを行い、以下の理由を含む結論を提示します。

検査項目 説明
未登録 パッケージがインストールされていない、entry-pointのグループ名が間違っている、または登録名とクエリ名が一致していない
ラグ遅延ロードがインスタンス化されていない 正常な状態であり、故障ではありません:ラグ遅延ロードモジュールは、最初に呼び出されたとき(module.call / コマンドがトリガーされるなど)にインスタンス化されます
設定で無効化されている ErisPulse.modules.status.<モジュール名> = false(未設定の場合はデフォルトで有効)
依存モジュールがロードされていない モジュールが宣言した depends リストに含まれるモジュールが準備ができていない
SDKバージョンが満たされていない モジュールのメタデータで宣言された min_sdk_version が現在のフレームワークバージョンより高い
on_load 例外 登録は正常だがロードされておらず、上記の理由もない場合——起動ログでモジュール名に対応する ERROR 記録を確認してください

返却される dict の構造化フィールドは以下の通りです:registered / loaded / lazy / enabled(None は未設定でデフォルトで有効を意味します)/ missing_dependencies / sdk_version_ok / conclusion(一文の結論)/ reasons(原因のリスト)。

シナリオ2:イベントが応答しない

from ErisPulse.runtime import explain_event, format_report

report = explain_event(event)   # プロセッサ内で取得した Event または元のイベント dict
print(format_report(report))

explain_event() は、イベントが実際に分発された順序に従って結果を出力します:

  1. プラットフォームアダプタが登録されていない:platform に対応するアダプタインスタンスが存在しない —— イベントはフレームワークにそもそも届いていない。
  2. アイデンティティの次元がスコープによって拒否されている:ユーザー / 会話 / Bot / アダプタがブロックされている —— イベントは分発の入口で完全に破棄される。スコープの設定はモジュール設定を参照してください。
  3. モジュールが会話によってブロックされている:現在の会話 available_modules(利用可能)と blocked_modules(スコープによってブロックされている)を区別する。
  4. コマンドのようなテキストだが、マッチしない:コマンドのプレフィックスを持ちながら、登録されたコマンドに一致しない —— プレフィックスの設定とコマンド名を確認してください。

入口のチェックがすべて通過しても応答がない場合、以下の2か所をさらに確認するよう指示されます:

シナリオ3:コマンドがトリガーされない(配信決定チェーン)

プレフィックス付きのメッセージが実際にコマンドを実行するには、次のように順番に通過する必要があります:コマンドテキスト判定 → コマンド一致(一致しなかった場合はスペル補正付き)→ スコープ → ユーザーACL → ホストチェック → 権限関数 → クールダウン / 限流 / 使用量による静かにドロップ → 廃棄拒否と通知 → パラメータ解析 → 実行。フレームワークは各判定ポイントを因果チェーンとして記録し、「なぜトリガーされなかったのか」の結論を提供します。

テスト中:TestBot.dispatch が DispatchTrace を返す

問題をテストで再現した後は、直接因果チェーンを読み取ることを推奨します(ツールの使い方はモジュールテストを参照):

trace = await bot.dispatch(create_command_event("dailyx", user_id="123"))

trace.verdict          # executed / rejected / dropped / failed / no_match / passed
print(trace.explain()) # 因果の逐次説明(現在の言語)
trace.assert_no_match()

フレームワークが内包する trace モジュール

決定チェーンは ErisPulse.Core.Event.trace によって提供され、デフォルトでゼロオーバーヘッドです——収集コンテキストにない場合は判定ポイントは直接スキップされ、本番経路上では感知されません:

from ErisPulse.Core.Event import (
    start_dispatch_trace,
    format_dispatch_trace,
    final_verdict,
)

with start_dispatch_trace() as records:
    ...  # 収集コンテキスト内で発生した配信(その派生したハンドラタスクを含む)

print(format_dispatch_trace(records))   # 人間が読める因果チェーン(現在の言語)
print(final_verdict(records))           # 総合的な結論

final_verdict() の値:

結論 含意
executed コマンドが実行された
rejected 権限クラスによる拒否(スコープ / ACL / ホスト / 権限関数)
dropped 静かにドロップされた(クールダウン / 限流 / 使用量 / ミドルウェアによる拒否)
failed 実行時にエラーが発生した
no_match プレフィックス付きだが、どのコマンドにも一致しなかった
passed コマンドテキストではなく、メッセージハンドラに渡す

記録は機械が読める dict として(stage / verdict / message_key / params)、stage でフィルタリングして表示できます(例:cooldown だけを見る)。

治理系の静かに一致した判定の識別

cooldown= / rate_limit= / usage_limit= が一致した場合、デフォルトで静かにドロップされます(コマンドは引き続き認識され、低優先度のハンドラには渡されません)。これは「コマンドが壊れている」誤解されやすい状況です:現象としては一部のユーザーでは使えるが、一部のユーザーでは応答がなく、決定チェーンに該当する stage の dropped 記録が表示されます。deprecated= コマンドは、呼び出し時に自動的に廃棄文案を返します(deprecated_reject=True の場合、実行を拒否します)。

一般的アドバイス