Improve out-of-credits warnings with structured provider details#325
Improve out-of-credits warnings with structured provider details#325marsmensch wants to merge 1 commit intoRunMaestro:mainfrom
Conversation
|
This was once of my mini todo items for testing the new codex update with my own prompts. I tried to keep the changes small and straightforward. Happy to address any issues and adapt the PR. Testing this with my own dev build for a few days already. Happy weekend! |
|
Amazing! This will help with #235! |
|
I was just looking at how https://github.com/steipete/CodexBar snags keys from local folders and hits the API. Previously I was trying to work it out purely via the CLI provider. But, whatever works. WIll analyze your PR today. |
|
@greptile review |
|
✅ Actions performedReview triggered.
|
📝 WalkthroughWalkthroughThis PR introduces structured error handling with pattern matching across Claude and Codex output parsers. It adds support for detecting quota exhaustion and credit limit errors as non-recoverable rate limits, extracts embedded JSON error data from outputs, and updates UI components to display rate limit information conditionally based on error recoverability status. Changes
Sequence Diagram(s)sequenceDiagram
participant Parser as Claude/Codex<br/>Output Parser
participant Extractor as Error Extraction<br/>Helpers
participant PatternMatcher as Error Pattern<br/>Matcher
participant ErrorObj as AgentError<br/>Object
Parser->>Extractor: extractErrorFromParsedLine/<br/>extractErrorFromMixedLine
Extractor-->>Parser: {errorText, parsedJson}
Parser->>PatternMatcher: buildPatternMatchedError<br/>(errorText, raw, parsedJson)
alt Pattern Matched
PatternMatcher-->>ErrorObj: Typed AgentError<br/>(rate_limited, unknown, etc.)
else No Pattern Match
Parser->>ErrorObj: buildUnknownStructuredError<br/>(errorText, raw, parsedJson)
end
ErrorObj-->>Parser: Return AgentError
sequenceDiagram
participant Modal as AgentErrorModal<br/>Component
participant Extractor as Rate Limit Info<br/>Extractors
participant UIRenderer as Modal UI<br/>Renderer
participant ErrorDisplay as Error Display<br/>Section
Modal->>Modal: Check if error.type<br/>=== 'rate_limited'
alt Is Rate Limited
Modal->>Extractor: extractRateLimitInfoLines<br/>(parsedJson)
Extractor->>Extractor: collectHeaderMaps<br/>(error.response_headers)
Extractor-->>Modal: rateLimitInfoLines[]
Modal->>UIRenderer: Render rate limit block<br/>(Usage Limit Reached)
UIRenderer->>ErrorDisplay: Show Retry-after,<br/>Request limits
else Not Rate Limited
Modal->>UIRenderer: Skip rate limit block
end
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches
🧪 Generate unit tests (beta)
Comment |
Greptile SummaryImproves out-of-credits error handling by preserving structured provider error payloads and distinguishing between recoverable rate-limiting and non-recoverable quota/credit exhaustion. Key Changes:
Impact: Confidence Score: 5/5
Important Files Changed
Flowchart%%{init: {'theme': 'neutral'}}%%
flowchart TD
A[Agent Process Exit] --> B{Parse stderr/stdout}
B --> C[Extract Structured JSON]
C --> D{JSON Found?}
D -->|Yes| E[Extract error message]
D -->|No| F[Pattern match raw text]
E --> G{Match Error Pattern?}
F --> G
G -->|Quota/Credit Pattern| H[Mark as rate_limited<br/>recoverable: false]
G -->|Rate Limit Pattern| I[Mark as rate_limited<br/>recoverable: true]
G -->|Other Pattern| J[Return matched error]
G -->|No Match + JSON| K[Return unknown type<br/>preserve parsedJson]
G -->|No Match + No JSON| L[Return agent_crashed]
H --> M[AgentErrorModal]
I --> M
J --> M
K --> M
L --> M
M --> N{error.type === rate_limited<br/>AND !recoverable?}
N -->|Yes| O[Title: Usage Limit Reached<br/>Extract rate limit headers]
N -->|No| P[Standard error display]
O --> Q[Display retry-after,<br/>requests/tokens limits]
P --> R[Show recovery actions]
Q --> R
Last reviewed commit: 0a5d275 |
There was a problem hiding this comment.
🧹 Nitpick comments (1)
src/main/parsers/codex-output-parser.ts (1)
451-535: Consider extracting shared error handling utilities.The error extraction methods (
extractErrorMessage,extractErrorFromParsedLine,buildPatternMatchedError,buildUnknownStructuredError,extractErrorFromMixedLine) are nearly identical toClaudeOutputParser. Consider extracting these into a shared base class or utility module to reduce duplication.♻️ Example shared utility approach
// src/main/parsers/error-extraction-utils.ts export function extractErrorMessage(errorField: unknown): string | null { ... } export function extractErrorFromMixedLine( line: string, extractFromParsed: (parsed: unknown) => ExtractedStructuredError ): ExtractedStructuredError { ... } export function buildPatternMatchedError( errorText: string, raw: NonNullable<AgentError['raw']>, patterns: AgentErrorPatterns, agentId: ToolType, parsedJson?: unknown ): AgentError | null { ... }Each parser would then import and use these utilities with their specific
agentIdand patterns.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/main/parsers/codex-output-parser.ts` around lines 451 - 535, The parser duplicates error-extraction logic found in ClaudeOutputParser (methods extractErrorMessage, extractErrorFromParsedLine, buildPatternMatchedError, buildUnknownStructuredError and extractErrorFromMixedLine); extract these into a shared utility module (e.g., error-extraction-utils) that exports functions like extractErrorMessage(errorField), extractErrorFromParsedLine(parsed) or extractErrorFromMixedLine(line, extractFromParsed), and buildPatternMatchedError(errorText, raw, patterns, agentId, parsedJson) so CodexOutputParser can import and call them (passing this.errorPatterns and this.agentId) instead of owning near-identical methods, then remove the duplicated methods from CodexOutputParser and update imports/usages accordingly.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@src/main/parsers/codex-output-parser.ts`:
- Around line 451-535: The parser duplicates error-extraction logic found in
ClaudeOutputParser (methods extractErrorMessage, extractErrorFromParsedLine,
buildPatternMatchedError, buildUnknownStructuredError and
extractErrorFromMixedLine); extract these into a shared utility module (e.g.,
error-extraction-utils) that exports functions like
extractErrorMessage(errorField), extractErrorFromParsedLine(parsed) or
extractErrorFromMixedLine(line, extractFromParsed), and
buildPatternMatchedError(errorText, raw, patterns, agentId, parsedJson) so
CodexOutputParser can import and call them (passing this.errorPatterns and
this.agentId) instead of owning near-identical methods, then remove the
duplicated methods from CodexOutputParser and update imports/usages accordingly.
Summary
Improve out-of-credits failures so users get actionable details instead of a generic
Agent exited with code 1.This intentionally avoids token-tracking complexity and uses structured provider error payloads/headers when available.
What changed
parsedJson) in parser output.type: unknown) to preserve provider error text when no known pattern matches.Usage Limit ReachedRate limit infosection from parsed headers (retry-after, request/token limits and reset values)Why
Scope
Only files directly involved in this feature were changed:
src/main/parsers/error-patterns.tssrc/main/parsers/claude-output-parser.tssrc/main/parsers/codex-output-parser.tssrc/renderer/components/AgentErrorModal.tsxsrc/renderer/hooks/agent/useAgentErrorRecovery.tsxsrc/renderer/App.tsxsrc/__tests__/main/parsers/error-patterns.test.tssrc/__tests__/main/parsers/claude-output-parser.test.tssrc/__tests__/main/parsers/codex-output-parser.test.tssrc/__tests__/renderer/components/AgentErrorModal.test.tsxValidation
npm run lintnpm run lint:eslintnpm test -- src/__tests__/main/parsers/error-patterns.test.ts src/__tests__/main/parsers/claude-output-parser.test.ts src/__tests__/main/parsers/codex-output-parser.test.ts src/__tests__/renderer/components/AgentErrorModal.test.tsx --silentnpm test -- src/__tests__/renderer/hooks/useAgentErrorRecovery.test.ts --silentSummary by CodeRabbit
Release Notes