mirror of
https://github.com/OpenRouterTeam/spawn.git
synced 2026-05-07 09:10:55 +00:00
fix: improve error messages with actionable guidance for common failures (#452)
- Add signal exit code handling (130/Ctrl+C, 137/killed, 255/SSH failure, 2/syntax error) - Replace vague "Cloud API retry logic exhausted" with attempt count and retry advice - Add network troubleshooting hint to API network error after retries - Clarify OAuth fallback prompt: explain why OAuth failed and what happens next - Consolidate auth cancellation message with three clear recovery options Agent: ux-engineer Co-authored-by: A <6723574+louisgv@users.noreply.github.com> Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
f2c9af0d79
commit
55fd4022e8
2 changed files with 29 additions and 12 deletions
|
|
@ -424,6 +424,17 @@ function reportDownloadError(ghUrl: string, err: unknown): never {
|
|||
|
||||
export function getScriptFailureGuidance(exitCode: number | null, cloud: string): string[] {
|
||||
switch (exitCode) {
|
||||
case 130:
|
||||
return ["Script was interrupted (Ctrl+C). No server was left running."];
|
||||
case 137:
|
||||
return ["Script was killed (likely by the system due to timeout or out of memory)."];
|
||||
case 255:
|
||||
return [
|
||||
"SSH connection failed. Common causes:",
|
||||
" - Server is still booting (wait a moment and retry)",
|
||||
" - Firewall blocking SSH port 22",
|
||||
" - Server was terminated before the session started",
|
||||
];
|
||||
case 127:
|
||||
return [
|
||||
"A required command was not found. Check that these are installed:",
|
||||
|
|
@ -432,6 +443,11 @@ export function getScriptFailureGuidance(exitCode: number | null, cloud: string)
|
|||
];
|
||||
case 126:
|
||||
return ["A command was found but could not be executed (permission denied)."];
|
||||
case 2:
|
||||
return [
|
||||
"Shell syntax or argument error. This is likely a bug in the script.",
|
||||
` Report it at: ${pc.cyan(`https://github.com/OpenRouterTeam/spawn/issues`)}`,
|
||||
];
|
||||
case 1:
|
||||
return [
|
||||
"Common causes:",
|
||||
|
|
|
|||
|
|
@ -747,14 +747,13 @@ get_openrouter_api_key_oauth() {
|
|||
|
||||
# OAuth failed, offer manual entry
|
||||
echo ""
|
||||
log_warn "OAuth authentication was not completed."
|
||||
log_info "You can enter your API key manually instead."
|
||||
log_info "Get a free key at: https://openrouter.ai/settings/keys"
|
||||
log_warn "Browser-based OAuth login was not completed (timed out or browser not available)."
|
||||
log_info "You can paste an API key instead. Create one at: https://openrouter.ai/settings/keys"
|
||||
echo ""
|
||||
local manual_choice
|
||||
manual_choice=$(safe_read "Would you like to enter your API key manually? (Y/n): ") || {
|
||||
manual_choice=$(safe_read "Paste your API key manually? (Y/n): ") || {
|
||||
log_error "Cannot prompt for manual entry in non-interactive mode"
|
||||
log_warn "Set OPENROUTER_API_KEY environment variable for non-interactive usage"
|
||||
log_warn "Set OPENROUTER_API_KEY environment variable before running spawn"
|
||||
return 1
|
||||
}
|
||||
|
||||
|
|
@ -763,12 +762,11 @@ get_openrouter_api_key_oauth() {
|
|||
echo "${api_key}"
|
||||
return 0
|
||||
else
|
||||
log_error "Authentication cancelled by user"
|
||||
log_error ""
|
||||
log_error "An OpenRouter API key is required to use spawn."
|
||||
log_error "Get your free API key at: https://openrouter.ai/settings/keys"
|
||||
log_error ""
|
||||
log_error "For non-interactive usage, set: OPENROUTER_API_KEY=sk-or-v1-..."
|
||||
log_error "Authentication cancelled. An OpenRouter API key is required to use spawn."
|
||||
log_warn "To authenticate, either:"
|
||||
log_warn " - Re-run this command and complete the OAuth flow in your browser"
|
||||
log_warn " - Set OPENROUTER_API_KEY=sk-or-v1-... before running spawn"
|
||||
log_warn " - Create a key at: https://openrouter.ai/settings/keys"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
|
@ -1112,6 +1110,7 @@ _handle_api_transient_error() {
|
|||
if [[ "${error_type}" == "network" ]]; then
|
||||
if ! _api_should_retry_on_error "network" "${attempt}" "${max_retries}" "${!interval_var}" "${!max_interval_var}" "Cloud API network error"; then
|
||||
log_error "Cloud API network error after ${max_retries} attempts"
|
||||
log_warn "Check your internet connection and verify the provider's API is reachable."
|
||||
return 1
|
||||
fi
|
||||
else
|
||||
|
|
@ -1166,7 +1165,9 @@ _cloud_api_retry_loop() {
|
|||
return 0
|
||||
done
|
||||
|
||||
log_error "Cloud API retry logic exhausted"
|
||||
log_error "Cloud API request failed after ${max_retries} attempts"
|
||||
log_warn "This is usually caused by rate limiting or temporary provider issues."
|
||||
log_warn "Wait a minute and try again, or check the provider's status page."
|
||||
return 1
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue