Skip to main content

Fehlerbehandlungs-Hook

Der onErrorOccurred Hook wird aufgerufen, wenn Während der Sitzungsausführung Fehler auftreten. Verwenden Sie es zu folgenden Zwecken:

  • Implementieren der benutzerdefinierten Fehlerprotokollierung
  • Nachverfolgen von Fehlermustern
  • Bereitstellen von benutzerfreundlichen Fehlermeldungen
  • Auslösen von Warnungen für kritische Fehler

Hook-Signatur

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

ErrorOccurredHandler = Callable[
    [ErrorOccurredHookInput, dict[str, str]],
    Awaitable[ErrorOccurredHookOutput | None]
]
ErrorOccurredHandler = Callable[
    [ErrorOccurredHookInput, dict[str, str]],
    Awaitable[ErrorOccurredHookOutput | None]
]
Go
package main

import copilot "github.com/github/copilot-sdk/go"

type ErrorOccurredHandler func(
    input copilot.ErrorOccurredHookInput,
    invocation copilot.HookInvocation,
) (*copilot.ErrorOccurredHookOutput, error)

func main() {}
type ErrorOccurredHandler func(
    input ErrorOccurredHookInput,
    invocation HookInvocation,
) (*ErrorOccurredHookOutput, error)
.NET
using GitHub.Copilot;

public delegate Task<ErrorOccurredHookOutput?> ErrorOccurredHandler(
    ErrorOccurredHookInput input,
    HookInvocation invocation);
public delegate Task<ErrorOccurredHookOutput?> ErrorOccurredHandler(
    ErrorOccurredHookInput input,
    HookInvocation invocation);
Java
// Note: Java SDK does not have an onErrorOccurred hook.
// Use EventErrorPolicy and EventErrorHandler instead:
//
// session.setEventErrorPolicy(EventErrorPolicy.SUPPRESS_AND_LOG_ERRORS);
// session.setEventErrorHandler((event, ex) -> {
//     System.err.println("Error in " + event.getType() + ": " + ex.getMessage());
// });
//
// See the "Basic Error Logging" example below for a complete snippet.

Eingabe

FeldTypDescription
timestampZahlUnix-Zeitstempel, wenn der Fehler aufgetreten ist
cwdstringAktuelles Arbeitsverzeichnis
errorstringFehlermeldung
errorContextstringWo der Fehler aufgetreten ist: "model_call", , "tool_execution", , "system"oder "user_input"
recoverablebooleanGibt an, ob der Fehler möglicherweise wiederhergestellt werden kann.

Output

Geben Sie null oder undefined zurück, um die standardmäßige Fehlerbehandlung zu verwenden. Geben Sie andernfalls ein Objekt mit den folgenden Eigenschaften zurück:

FeldTypDescription
suppressOutputbooleanWenn "true" ist, wird die Fehlerausgabe für den Benutzer nicht angezeigt.
errorHandlingstringBehandeln von: "retry", "skip", oder "abort"
retryCountZahlAnzahl der Wiederholungsversuche (wenn "errorHandling" lautet "retry")
userNotificationstringBenutzerdefinierte Nachricht für den Benutzer anzeigen

Examples

Grundlegende Fehlerprotokollierung

TypeScript
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
from copilot.session import PermissionHandler

async def on_error_occurred(input_data, invocation):
    print(f"[{invocation['session_id']}] Error: {input_data['error']}")
    print(f"  Context: {input_data['errorContext']}")
    print(f"  Recoverable: {input_data['recoverable']}")
    return None

session = await client.create_session(on_permission_request=PermissionHandler.approve_all, hooks={"on_error_occurred": on_error_occurred})
Go
package main

import (
    "context"
    "fmt"
    copilot "github.com/github/copilot-sdk/go"
)

func main() {
    client := copilot.NewClient(nil)
    session, _ := client.CreateSession(context.Background(), &copilot.SessionConfig{
        OnPermissionRequest: copilot.PermissionHandler.ApproveAll,
        Hooks: &copilot.SessionHooks{
            OnErrorOccurred: func(input copilot.ErrorOccurredHookInput, inv copilot.HookInvocation) (*copilot.ErrorOccurredHookOutput, error) {
                fmt.Printf("[%s] Error: %s\n", inv.SessionID, input.Error)
                fmt.Printf("  Context: %s\n", input.ErrorContext)
                fmt.Printf("  Recoverable: %v\n", input.Recoverable)
                return nil, nil
            },
        },
    })
    _ = session
}
session, _ := client.CreateSession(context.Background(), &copilot.SessionConfig{
    Hooks: &copilot.SessionHooks{
        OnErrorOccurred: func(input copilot.ErrorOccurredHookInput, inv copilot.HookInvocation) (*copilot.ErrorOccurredHookOutput, error) {
            fmt.Printf("[%s] Error: %s\n", inv.SessionID, input.Error)
            fmt.Printf("  Context: %s\n", input.ErrorContext)
            fmt.Printf("  Recoverable: %v\n", input.Recoverable)
            return nil, nil
        },
    },
})
.NET
using GitHub.Copilot;

public static class ErrorHandlingExample
{
    public static async Task Main()
    {
        await using var client = new CopilotClient();
        var session = await client.CreateSessionAsync(new SessionConfig
        {
            Hooks = new SessionHooks
            {
                OnErrorOccurred = (input, invocation) =>
                {
                    Console.Error.WriteLine($"[{invocation.SessionId}] Error: {input.Error}");
                    Console.Error.WriteLine($"  Context: {input.ErrorContext}");
                    Console.Error.WriteLine($"  Recoverable: {input.Recoverable}");
                    return Task.FromResult<ErrorOccurredHookOutput?>(null);
                },
            },
        });
    }
}
var session = await client.CreateSessionAsync(new SessionConfig
{
    Hooks = new SessionHooks
    {
        OnErrorOccurred = (input, invocation) =>
        {
            Console.Error.WriteLine($"[{invocation.SessionId}] Error: {input.Error}");
            Console.Error.WriteLine($"  Context: {input.ErrorContext}");
            Console.Error.WriteLine($"  Recoverable: {input.Recoverable}");
            return Task.FromResult<ErrorOccurredHookOutput?>(null);
        },
    },
});
Java
import com.github.copilot.sdk.*;
import com.github.copilot.sdk.json.*;

// Note: Java SDK does not have an onErrorOccurred hook.
// Use EventErrorPolicy and EventErrorHandler instead:

var session = client.createSession(
    new SessionConfig()
        .setOnPermissionRequest(PermissionHandler.APPROVE_ALL)
).get();

session.setEventErrorPolicy(EventErrorPolicy.SUPPRESS_AND_LOG_ERRORS);
session.setEventErrorHandler((event, ex) -> {
    System.err.println("[" + session.getSessionId() + "] Error: " + ex.getMessage());
    System.err.println("  Event: " + event.getType());
});

Fehler an den Überwachungsdienst senden

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;
    },
  },
});

Benutzerfreundliche Fehlermeldungen

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;
    },
  },
});

Unterdrücken nicht kritischer Fehler

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;
    },
  },
});

Hinzufügen des Wiederherstellungskontexts

const session = await client.createSession({
  hooks: {
    onErrorOccurred: async (input) => {
      if (input.errorContext === "tool_execution") {
        return {
          userNotification: `
The tool failed. Here are some recovery suggestions:
- Check if required dependencies are installed
- Verify file paths are correct
- Try a simpler approach
          `.trim(),
        };
      }
      
      if (input.errorContext === "model_call" && input.error.includes("rate")) {
        return {
          errorHandling: "retry",
          retryCount: 3,
          userNotification: "Rate limit hit. Retrying...",
        };
      }
      
      return null;
    },
  },
});

Nachverfolgen von Fehlermustern

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;
    },
  },
});

Warnung bei kritischen Fehlern

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;
    },
  },
});

Kombinieren mit anderen Hooks für Kontext

const sessionContext = new Map<string, { lastTool?: string; lastPrompt?: string }>();

const session = await client.createSession({
  hooks: {
    onPreToolUse: async (input, invocation) => {
      const ctx = sessionContext.get(invocation.sessionId) || {};
      ctx.lastTool = input.toolName;
      sessionContext.set(invocation.sessionId, ctx);
      return { permissionDecision: "allow" };
    },
    
    onUserPromptSubmitted: async (input, invocation) => {
      const ctx = sessionContext.get(invocation.sessionId) || {};
      ctx.lastPrompt = input.prompt.substring(0, 100);
      sessionContext.set(invocation.sessionId, ctx);
      return null;
    },
    
    onErrorOccurred: async (input, invocation) => {
      const ctx = sessionContext.get(invocation.sessionId);
      
      console.error(`Error in session ${invocation.sessionId}:`);
      console.error(`  Error: ${input.error}`);
      console.error(`  Context: ${input.errorContext}`);
      if (ctx?.lastTool) {
        console.error(`  Last tool: ${ctx.lastTool}`);
      }
      if (ctx?.lastPrompt) {
        console.error(`  Last prompt: ${ctx.lastPrompt}...`);
      }
      
      return null;
    },
  },
});

Bewährte Methoden

  1. Immer Protokollieren von Fehlern – Auch wenn Sie sie von Benutzern unterdrücken, behalten Sie Protokolle für das Debuggen bei.

  2. Kategorisieren von Fehlern – Verwenden Sie errorType diese, um unterschiedliche Fehler angemessen zu behandeln.

  3. Verschlucken Sie keine kritischen Fehler – Nur Fehler unterdrücken, die Sie sicher sind, sind nicht kritisch.

  4. Hooks schnell halten – Die Fehlerbehandlung sollte die Wiederherstellung nicht verlangsamen.

  5. Hilfreichen Kontext bereitstellen – Wenn Fehler auftreten, additionalContext kann dem Modell helfen, sich zu erholen.

  6. Überwachen von Fehlermustern – Verfolgen Sie wiederkehrende Fehler, um systemische Probleme zu identifizieren.

Siehe auch