Skip to main content

エラー処理フック

          `onErrorOccurred` フックを使用して、カスタム エラー ログを実装し、エラー パターンを追跡し、Copilot SDKでわかりやすいエラー メッセージを提供します。

この機能を使用できるユーザーについて

GitHub Copilot SDK は、すべての Copilot プランで使用できます。

メモ

Copilot SDK は現在 テクニカル プレビューです。 機能と可用性は変更される場合があります。

          `onErrorOccurred` フックは、セッションの実行中にエラーが発生したときに呼び出されます。 これは次の目的で使用されます。
  • カスタム エラー ログを実装する
  • エラー パターンを追跡する
  • わかりやすいエラー メッセージを提供する
  • 重大なエラーのアラートをトリガーする

フック署名

import type { ErrorOccurredHookInput, HookInvocation, ErrorOccurredHookOutput } from "@github/copilot-sdk";
type ErrorOccurredHandler = (
  input: ErrorOccurredHookInput,
  invocation: HookInvocation
) => Promise<
  ErrorOccurredHookOutput | null | undefined
>;

Python、Go、.NET のフック署名については、 github/copilot-sdk リポジトリを参照してください。

入力

フィールドタイプ説明
timestamp数値エラーが発生したときの Unix タイムスタンプ
cwd文字列現在の作業ディレクトリ
error文字列エラー メッセージ
errorContext文字列エラーが発生した場所: "model_call""tool_execution""system"、または "user_input"
recoverableブーリアンエラーを復旧できる可能性があるかどうか

アウトプット

既定のエラー処理を使用するには、 null または undefined を返します。 それ以外の場合は、次のいずれかのフィールドを持つオブジェクトを返します。

フィールドタイプ説明
suppressOutputブーリアンtrue、エラー出力をユーザーに表示しない
errorHandling文字列処理方法: "retry""skip"、または "abort"
retryCount数値再試行する回数 ( errorHandling"retry"の場合)
userNotification文字列ユーザーを表示するカスタム メッセージ

例示

基本的なエラー ログ

const session = await client.createSession({
  hooks: {
    onErrorOccurred: async (
      input, invocation
    ) => {
      console.error(
        `[${invocation.sessionId}] `
        + `Error: ${input.error}`
      );
      console.error(
        `  Context: ${input.errorContext}`
      );
      console.error(
        `  Recoverable: ${input.recoverable}`
      );
      return null;
    },
  },
});

Python、Go、.NET の例については、 github/copilot-sdk リポジトリを参照してください。

監視サービスにエラーを送信する

import { captureException } from "@sentry/node"; // or your monitoring service

const session = await client.createSession({
  hooks: {
    onErrorOccurred: async (input, invocation) => {
      captureException(new Error(input.error), {
        tags: {
          sessionId: invocation.sessionId,
          errorContext: input.errorContext,
        },
        extra: {
          error: input.error,
          recoverable: input.recoverable,
          cwd: input.cwd,
        },
      });
      
      return null;
    },
  },
});

わかりやすいエラー メッセージ

const ERROR_MESSAGES: Record<string, string> = {
  "model_call":
    "There was an issue communicating "
    + "with the AI model. Please try again.",
  "tool_execution":
    "A tool failed to execute. "
    + "Please check your inputs and try again.",
  "system":
    "A system error occurred. "
    + "Please try again later.",
  "user_input":
    "There was an issue with your input. "
    + "Please check and try again.",
};

const session = await client.createSession({
  hooks: {
    onErrorOccurred: async (input) => {
      const friendlyMessage =
        ERROR_MESSAGES[input.errorContext];

      if (friendlyMessage) {
        return {
          userNotification: friendlyMessage,
        };
      }

      return null;
    },
  },
});

重大でないエラーを抑制する

const session = await client.createSession({
  hooks: {
    onErrorOccurred: async (input) => {
      // Suppress tool execution errors
      // that are recoverable
      if (
        input.errorContext === "tool_execution"
        && input.recoverable
      ) {
        console.log(
          `Suppressed recoverable error: `
          + `${input.error}`
        );
        return { suppressOutput: true };
      }
      return null;
    },
  },
});

回復コンテキストの追加

const session = await client.createSession({
  hooks: {
    onErrorOccurred: async (input) => {
      if (
        input.errorContext === "tool_execution"
      ) {
        return {
          userNotification:
            "The tool failed. Here are some "
            + "recovery suggestions:\n"
            + "- Check if required dependencies "
            + "are installed\n"
            + "- Verify file paths are correct\n"
            + "- Try a simpler approach",
        };
      }

      if (
        input.errorContext === "model_call"
        && input.error.includes("rate")
      ) {
        return {
          errorHandling: "retry",
          retryCount: 3,
          userNotification:
            "Rate limit hit. Retrying...",
        };
      }

      return null;
    },
  },
});

エラー パターンを追跡する

interface ErrorStats {
  count: number;
  lastOccurred: number;
  contexts: string[];
}

const errorStats =
  new Map<string, ErrorStats>();

const session = await client.createSession({
  hooks: {
    onErrorOccurred: async (
      input, invocation
    ) => {
      const key =
        `${input.errorContext}:`
        + `${input.error.substring(0, 50)}`;

      const existing =
        errorStats.get(key) || {
          count: 0,
          lastOccurred: 0,
          contexts: [],
        };

      existing.count++;
      existing.lastOccurred = input.timestamp;
      existing.contexts.push(
        invocation.sessionId
      );

      errorStats.set(key, existing);

      // Alert if error is recurring
      if (existing.count >= 5) {
        console.warn(
          `Recurring error detected: `
          + `${key} (${existing.count} times)`
        );
      }

      return null;
    },
  },
});

重大なエラーに関するアラート

const CRITICAL_CONTEXTS = [
  "system", "model_call",
];

const session = await client.createSession({
  hooks: {
    onErrorOccurred: async (
      input, invocation
    ) => {
      if (
        CRITICAL_CONTEXTS.includes(
          input.errorContext
        )
        && !input.recoverable
      ) {
        await sendAlert({
          level: "critical",
          message:
            `Critical error in session `
            + `${invocation.sessionId}`,
          error: input.error,
          context: input.errorContext,
          timestamp: new Date(
            input.timestamp
          ).toISOString(),
        });
      }

      return null;
    },
  },
});

ベスト プラクティス

  •         **常にエラーをログに記録します。** ユーザーから非表示にした場合でも、デバッグのためにログを保持します。
    
  •         **エラーを分類します。** 
            `errorContext`を使用して、さまざまなエラーを適切に処理します。
    
  •         **重大なエラーを飲み込まないでください。** 重要でないと確信しているエラーのみを抑制します。
    
  •         **フックをしっかりと固定してください。** エラー処理によって回復速度が低下しないようにする必要があります。
    
  •         **エラー パターンを監視します。** 定期的なエラーを追跡して、全身的な問題を特定します。
    

詳細については、次を参照してください。

  •         [AUTOTITLE](/copilot/how-tos/copilot-sdk/use-hooks/quickstart)
    
  •         [AUTOTITLE](/copilot/how-tos/copilot-sdk/use-hooks/session-lifecycle)
    
  •         [AUTOTITLE](/copilot/how-tos/copilot-sdk/use-hooks/pre-tool-use)