Exception: ClaudeAgentSDK::ResultError
- Inherits:
-
ProcessError
- Object
- StandardError
- ClaudeSDKError
- ProcessError
- ClaudeAgentSDK::ResultError
- Defined in:
- lib/claude_agent_sdk/errors.rb
Overview
Raised when the CLI exits after reporting a terminal error result.
The CLI ends a failed run by emitting a result message with
is_error: true (yielded to you as a ResultMessage) and then exiting
non-zero, on purpose, for shell-script consumers. This exception replaces
the bare "exit code 1" ProcessError for that case and carries the
result's payload, so callers can branch on why the run failed without
string matching:
begin
ClaudeAgentSDK.query(prompt: '...') { |message| ... }
rescue ClaudeAgentSDK::ResultError => e
if e.terminal_reason == 'api_error' # e.g. overloaded / timeout
retry_later
elsif e.subtype == 'error_max_turns'
...
end
end
It subclasses ProcessError, so existing rescue ProcessError handlers
keep working.
Every structured field is type-narrowed: a payload whose subtype is not
a String (or whose api_error_status is not an Integer, ...) reads back
as nil rather than leaking the raw value, so callers can branch on these
without re-validating. #data always holds the payload as the CLI sent it.
Instance Attribute Summary collapse
-
#api_error_status ⇒ Object
readonly
HTTP status of the failing API call, if any.
-
#data ⇒ Object
readonly
The raw
resultmessage payload as emitted by the CLI. -
#errors ⇒ Object
readonly
Error strings reported by the CLI (may be empty).
-
#original_error ⇒ Object
readonly
The ProcessError this replaced (the bare "exit code 1" exit).
-
#result ⇒ Object
readonly
The result text, if any.
-
#session_id ⇒ Object
readonly
Session the result belongs to, if reported.
-
#subtype ⇒ Object
readonly
The result subtype ("error_max_turns", "error_during_execution", ... — or "success" when the agent loop itself completed but the last turn was an API error).
-
#terminal_reason ⇒ Object
readonly
Why the run ended (e.g. "api_error", "max_turns"), if reported.
Attributes inherited from ProcessError
Class Method Summary collapse
-
.error_text(data) ⇒ Object
Pick the most informative text from a
resultframe with is_error.
Instance Method Summary collapse
-
#initialize(message, data: nil, exit_code: nil, stderr: nil, original_error: nil) ⇒ ResultError
constructor
A new instance of ResultError.
Constructor Details
#initialize(message, data: nil, exit_code: nil, stderr: nil, original_error: nil) ⇒ ResultError
Returns a new instance of ResultError.
167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 |
# File 'lib/claude_agent_sdk/errors.rb', line 167 def initialize(, data: nil, exit_code: nil, stderr: nil, original_error: nil) data = {} unless data.is_a?(Hash) @data = data @original_error = original_error subtype = Payload.field(data, :subtype) @subtype = subtype.is_a?(String) ? subtype : nil @errors = Payload.normalize_errors(Payload.field(data, :errors)) result = Payload.field(data, :result) @result = result.is_a?(String) ? result : nil status = Payload.field(data, :api_error_status) @api_error_status = status.is_a?(Integer) ? status : nil reason = Payload.field(data, :terminal_reason) @terminal_reason = reason.is_a?(String) ? reason : nil session_id = Payload.field(data, :session_id) @session_id = session_id.is_a?(String) ? session_id : nil super(, exit_code: exit_code, stderr: stderr) end |
Instance Attribute Details
#api_error_status ⇒ Object (readonly)
HTTP status of the failing API call, if any.
82 83 84 |
# File 'lib/claude_agent_sdk/errors.rb', line 82 def api_error_status @api_error_status end |
#data ⇒ Object (readonly)
The raw result message payload as emitted by the CLI.
91 92 93 |
# File 'lib/claude_agent_sdk/errors.rb', line 91 def data @data end |
#errors ⇒ Object (readonly)
Error strings reported by the CLI (may be empty). Normalized the same way the exception text is built, so the two never disagree.
75 76 77 |
# File 'lib/claude_agent_sdk/errors.rb', line 75 def errors @errors end |
#original_error ⇒ Object (readonly)
The ProcessError this replaced (the bare "exit code 1" exit).
Ruby only populates #cause for an exception raised inside a rescue block; the read loop hands this one to the message queue instead of raising it there, so #cause is nil and the original exit error would be lost without an explicit accessor. Mirrors Python's cause chaining.
99 100 101 |
# File 'lib/claude_agent_sdk/errors.rb', line 99 def original_error @original_error end |
#result ⇒ Object (readonly)
The result text, if any. For API failures this holds the "API Error: ..." prose.
79 80 81 |
# File 'lib/claude_agent_sdk/errors.rb', line 79 def result @result end |
#session_id ⇒ Object (readonly)
Session the result belongs to, if reported.
88 89 90 |
# File 'lib/claude_agent_sdk/errors.rb', line 88 def session_id @session_id end |
#subtype ⇒ Object (readonly)
The result subtype ("error_max_turns", "error_during_execution", ... — or "success" when the agent loop itself completed but the last turn was an API error).
71 72 73 |
# File 'lib/claude_agent_sdk/errors.rb', line 71 def subtype @subtype end |
#terminal_reason ⇒ Object (readonly)
Why the run ended (e.g. "api_error", "max_turns"), if reported.
85 86 87 |
# File 'lib/claude_agent_sdk/errors.rb', line 85 def terminal_reason @terminal_reason end |
Class Method Details
.error_text(data) ⇒ Object
Pick the most informative text from a result frame with is_error.
Terminal errors the CLI raises itself (error_max_turns,
error_during_execution, ...) carry their prose in errors. A run that
ends on an API failure instead arrives as subtype "success" with
is_error true, an empty errors and the "API Error: ..." prose in
result — falling back to the subtype there produced the self-
contradictory "Claude Code returned an error result: success". Prefer
errors, then result, then a non-success subtype, then the HTTP
status, mirroring the TypeScript SDK's choice of result for the
success subtype.
Public because the read loop builds the exception message from it, and because it is the documented way to get the same one-line summary out of a raw error result you already hold (an is_error ResultMessage the CLI emitted before exiting). Mirrors Python's _error_result_text.
151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 |
# File 'lib/claude_agent_sdk/errors.rb', line 151 def self.error_text(data) errors = Payload.normalize_errors(Payload.field(data, :errors)) return errors.join('; ') unless errors.empty? result = Payload.field(data, :result) return result.strip if result.is_a?(String) && !result.strip.empty? subtype = Payload.field(data, :subtype) return subtype if subtype.is_a?(String) && !subtype.empty? && subtype != 'success' status = Payload.field(data, :api_error_status) return "API error (HTTP #{status})" unless status.nil? 'unknown error' end |