Fix hooks to fail gracefully instead of blocking user prompts
Three issues fixed: 1. session-init handler: Worker 500 errors caused `throw`, which hook-command.ts caught and exited with code 2 (blocking error). This blocked the user's prompt entirely with: "Hook error: Error: Session initialization failed: 500" Fix: Log the failure and return SUCCESS so the prompt proceeds. 2. user-message handler: Referenced nonexistent constant HOOK_EXIT_CODES.USER_MESSAGE_ONLY (undefined). Also used console.error() for informational output, which Claude Code may flag as an error. Fix: Use process.stderr.write() and return HOOK_EXIT_CODES.SUCCESS explicitly. 3. Both handlers threw on HTTP errors from the worker, causing exit code 2 (blocking). Memory plugin failures should never prevent users from using Claude Code. All worker HTTP failures now log and return gracefully. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
committed by
Alex Newman
parent
311d62cc02
commit
67f9d631bd
@@ -43,7 +43,9 @@ export const sessionInitHandler: EventHandler = {
|
||||
});
|
||||
|
||||
if (!initResponse.ok) {
|
||||
throw new Error(`Session initialization failed: ${initResponse.status}`);
|
||||
// Log but don't throw - a worker 500 should not block the user's prompt
|
||||
logger.failure('HOOK', `Session initialization failed: ${initResponse.status}`, { contentSessionId: sessionId, project });
|
||||
return { continue: true, suppressOutput: true, exitCode: HOOK_EXIT_CODES.SUCCESS };
|
||||
}
|
||||
|
||||
const initResult = await initResponse.json() as {
|
||||
@@ -86,7 +88,8 @@ export const sessionInitHandler: EventHandler = {
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`SDK agent start failed: ${response.status}`);
|
||||
// Log but don't throw - SDK agent failure should not block the user's prompt
|
||||
logger.failure('HOOK', `SDK agent start failed: ${response.status}`, { sessionDbId, promptNumber });
|
||||
}
|
||||
} else if (input.platform === 'cursor') {
|
||||
logger.debug('HOOK', 'session-init: Skipping SDK agent init for Cursor platform', { sessionDbId, promptNumber });
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/**
|
||||
* User Message Handler - SessionStart (parallel)
|
||||
*
|
||||
* Extracted from user-message-hook.ts - displays context info to user via stderr.
|
||||
* Uses exit code 3 to show user message without injecting into Claude's context.
|
||||
* Displays context info to user via stderr.
|
||||
* Uses exit code 0 (SUCCESS) - stderr is not shown to Claude with exit 0.
|
||||
*/
|
||||
|
||||
import { basename } from 'path';
|
||||
@@ -26,21 +26,24 @@ export const userMessageHandler: EventHandler = {
|
||||
);
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`Failed to fetch context: ${response.status}`);
|
||||
// Don't throw - context fetch failure should not block the user's prompt
|
||||
return { exitCode: HOOK_EXIT_CODES.SUCCESS };
|
||||
}
|
||||
|
||||
const output = await response.text();
|
||||
|
||||
// Write to stderr for user visibility (Claude Code UI shows stderr)
|
||||
console.error(
|
||||
"\n\n" + String.fromCodePoint(0x1F4DD) + " Claude-Mem Context Loaded\n" +
|
||||
" " + String.fromCodePoint(0x2139, 0xFE0F) + " Note: This appears as stderr but is informational only\n\n" +
|
||||
// Write to stderr for user visibility
|
||||
// Note: Using process.stderr.write instead of console.error to avoid
|
||||
// Claude Code treating this as a hook error. The actual hook output
|
||||
// goes to stdout via hook-command.ts JSON serialization.
|
||||
process.stderr.write(
|
||||
"\n\n" + String.fromCodePoint(0x1F4DD) + " Claude-Mem Context Loaded\n\n" +
|
||||
output +
|
||||
"\n\n" + String.fromCodePoint(0x1F4A1) + " New! Wrap all or part of any message with <private> ... </private> to prevent storing sensitive information in your observation history.\n" +
|
||||
"\n\n" + String.fromCodePoint(0x1F4A1) + " Wrap any message with <private> ... </private> to prevent storing sensitive information.\n" +
|
||||
"\n" + String.fromCodePoint(0x1F4AC) + " Community https://discord.gg/J4wttp9vDu" +
|
||||
`\n` + String.fromCodePoint(0x1F4FA) + ` Watch live in browser http://localhost:${port}/\n`
|
||||
);
|
||||
|
||||
return { exitCode: HOOK_EXIT_CODES.USER_MESSAGE_ONLY };
|
||||
return { exitCode: HOOK_EXIT_CODES.SUCCESS };
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user