Errors¶
SelfAgency defines a hierarchy of errors under SelfAgency::Error.
Hierarchy¶
StandardError
└── SelfAgency::Error
├── SelfAgency::GenerationError
├── SelfAgency::ValidationError
└── SelfAgency::SecurityError
All SelfAgency errors inherit from SelfAgency::Error, which inherits from StandardError. This means you can catch all SelfAgency errors with a single rescue:
SelfAgency::Error¶
Base error class. Also raised directly when configuration is missing.
Raised when:
_()is called beforeSelfAgency.configure_save!is called with no generated methods_save!is called on an anonymous class
SelfAgency.reset!
Widget.new._("a method")
#=> SelfAgency::Error: SelfAgency.configure has not been called
SelfAgency::GenerationError¶
Raised when the LLM fails to produce output or when an LLM communication failure occurs.
Attributes:
| Attribute | Type | Description |
|---|---|---|
stage |
Symbol or nil |
:shape or :generate -- which pipeline stage failed |
attempt |
Integer or nil |
The attempt number (during retry loop) |
Raised when:
- The shape stage returns
nil-- message:"Prompt shaping failed (LLM returned nil)" - The generate stage returns
nil-- message:"Code generation failed (LLM returned nil)" - An LLM communication failure occurs -- message:
"LLM request failed (ExceptionClass: details)"
Note
LLM communication failures (network errors, timeouts, provider API errors) are wrapped and re-raised as GenerationError. The original exception class and message are preserved in the error message. If generation consistently fails, verify your LLM provider is running and the configuration (provider, model, api_base) is correct.
SelfAgency::ValidationError¶
Raised when the generated code fails structural or syntactic validation.
Attributes:
| Attribute | Type | Description |
|---|---|---|
generated_code |
String or nil |
The code that failed validation |
attempt |
Integer or nil |
The attempt number (during retry loop) |
Raised when:
- Generated code is empty after sanitization
- Generated code does not contain a
def...endstructure - Generated code has a syntax error (
RubyVM::InstructionSequence.compilefails)
Note
During automatic retries, ValidationError is only raised to the caller after all generation_retries attempts are exhausted. The attempt attribute indicates which attempt produced the final failure.
# Empty code
widget.send(:self_agency_validate!, "")
#=> SelfAgency::ValidationError: code is empty
# Missing def...end
widget.send(:self_agency_validate!, "puts 'hello'")
#=> SelfAgency::ValidationError: missing def...end structure
# Syntax error
widget.send(:self_agency_validate!, "def broken\n if true\nend")
#=> SelfAgency::ValidationError: syntax error: ...
SelfAgency::SecurityError¶
Raised when the generated code contains a dangerous pattern.
Attributes:
| Attribute | Type | Description |
|---|---|---|
matched_pattern |
String or nil |
The specific pattern text that was matched |
generated_code |
String or nil |
The code that triggered the error |
Raised when:
- The code matches
SelfAgency::DANGEROUS_PATTERNS(static analysis)
The error message includes the specific matched pattern, e.g., "dangerous pattern detected: system".
Note
This is SelfAgency::SecurityError, distinct from Ruby's built-in ::SecurityError. The runtime sandbox raises ::SecurityError (the Ruby built-in), while the static validator raises SelfAgency::SecurityError.
# System call
widget.send(:self_agency_validate!, "def hack\n system('ls')\nend")
#=> SelfAgency::SecurityError: dangerous pattern detected: system
# File access
widget.send(:self_agency_validate!, "def hack\n File.read('/etc/passwd')\nend")
#=> SelfAgency::SecurityError: dangerous pattern detected: File.
# Eval
widget.send(:self_agency_validate!, "def hack\n eval('1+1')\nend")
#=> SelfAgency::SecurityError: dangerous pattern detected: eval
Error Handling Patterns¶
Catch All SelfAgency Errors¶
begin
obj._("a method description")
rescue SelfAgency::Error => e
puts "#{e.class}: #{e.message}"
end
Catch Specific Errors¶
begin
obj._("a method description")
rescue SelfAgency::GenerationError => e
puts "LLM failed at #{e.stage} stage (attempt #{e.attempt}): #{e.message}"
rescue SelfAgency::ValidationError => e
puts "Validation failed on attempt #{e.attempt}: #{e.message}"
puts "Code was: #{e.generated_code}" if e.generated_code
rescue SelfAgency::SecurityError => e
puts "Security: matched '#{e.matched_pattern}' in generated code"
end