Module: ClaudeMemory::Hook::ErrorClassifier

Defined in:
lib/claude_memory/hook/error_classifier.rb

Overview

Classifies hook errors into transport/infrastructure failures vs client/programming bugs to determine exit code behavior.

Transport errors (exit 0): Infrastructure failures that shouldn’t block Claude Code sessions. Memory is optional — degrade gracefully.

Client errors (exit 2): Programming bugs or invalid input that developers should see and fix.

Source: claude-mem hook-command.ts:26-66

Constant Summary collapse

TRANSPORT_ERROR_NAMES =

Infrastructure/transport error class names — resolved lazily to avoid load-order dependency on Sequel

%w[
  Sequel::DatabaseConnectionError
  Sequel::DatabaseError
].freeze
TRANSPORT_ERROR_CLASSES =
[
  Errno::EACCES,
  Errno::ENOSPC,
  Errno::EISDIR,
  Errno::EROFS,
  IOError
].freeze
CLIENT_ERROR_CLASSES =

Client/programming error classes — surface to developer

[
  Handler::PayloadError,
  JSON::ParserError,
  TypeError,
  NoMethodError,
  ArgumentError
].freeze

Class Method Summary collapse

Class Method Details

.client_error?(error) ⇒ Boolean

Returns true for programming bugs that developers should fix

Returns:

  • (Boolean)


49
50
51
# File 'lib/claude_memory/hook/error_classifier.rb', line 49

def client_error?(error)
  CLIENT_ERROR_CLASSES.any? { |klass| error.is_a?(klass) }
end

.exit_code_for(error) ⇒ Object

Returns the appropriate exit code for an error



54
55
56
57
58
59
60
61
62
63
64
# File 'lib/claude_memory/hook/error_classifier.rb', line 54

def exit_code_for(error)
  if transport_error?(error)
    ExitCodes::SUCCESS
  elsif client_error?(error)
    ExitCodes::ERROR
  else
    # Unknown errors default to graceful degradation —
    # memory should never block Claude Code sessions
    ExitCodes::SUCCESS
  end
end

.transport_error?(error) ⇒ Boolean

Returns true for infrastructure failures that should not block sessions

Returns:

  • (Boolean)


43
44
45
46
# File 'lib/claude_memory/hook/error_classifier.rb', line 43

def transport_error?(error)
  TRANSPORT_ERROR_CLASSES.any? { |klass| error.is_a?(klass) } ||
    TRANSPORT_ERROR_NAMES.any? { |name| error.class.ancestors.any? { |a| a.name == name } }
end