MCPcopy Index your code
hub / github.com/ChrisFeldmeier/OpenCodeRust / error_from_anyhow

Function error_from_anyhow

crates/opencode-session/src/message_v2.rs:592–699  ·  view source on GitHub ↗

Convert an arbitrary error into a [`MessageError`]. This mirrors the TS `MessageV2.fromError` function. It inspects the error chain for well-known provider error types and falls back to `Unknown`.

(e: anyhow::Error, provider_id: &str)

Source from the content-addressed store, hash-verified

590/// This mirrors the TS `MessageV2.fromError` function. It inspects the error
591/// chain for well-known provider error types and falls back to `Unknown`.
592pub fn error_from_anyhow(e: anyhow::Error, provider_id: &str) -> MessageError {
593 let err_str = e.to_string();
594
595 // 1. AbortError – the operation was cancelled / aborted.
596 if err_str.contains("abort") || err_str.contains("cancelled") || err_str.contains("AbortError")
597 {
598 return MessageError::AbortedError { message: err_str };
599 }
600
601 // 2. OutputLengthError – model hit its max output token limit.
602 if err_str.contains("output length")
603 || err_str.contains("max_tokens")
604 || err_str.contains("output_length")
605 || err_str.contains("OutputLengthError")
606 {
607 return MessageError::OutputLengthError { message: err_str };
608 }
609
610 // 3. AuthError – API key / credential issues.
611 if err_str.contains("auth")
612 || err_str.contains("api key")
613 || err_str.contains("API key")
614 || err_str.contains("LoadAPIKeyError")
615 || err_str.contains("unauthorized")
616 || err_str.contains("Unauthorized")
617 {
618 return MessageError::AuthError {
619 provider_id: provider_id.to_string(),
620 message: err_str,
621 };
622 }
623
624 // 4. ECONNRESET / connection reset.
625 if err_str.contains("ECONNRESET")
626 || err_str.contains("connection reset")
627 || err_str.contains("Connection reset")
628 {
629 let mut metadata = HashMap::new();
630 metadata.insert("code".to_string(), "ECONNRESET".to_string());
631 metadata.insert("message".to_string(), err_str.clone());
632 return MessageError::ApiError {
633 message: "Connection reset by server".to_string(),
634 status_code: None,
635 is_retryable: true,
636 response_headers: None,
637 response_body: None,
638 metadata: Some(metadata),
639 };
640 }
641
642 // 5. Try to downcast to ProviderError for structured handling.
643 if let Some(provider_err) = e.downcast_ref::<ProviderError>() {
644 let parsed = parse_api_call_error(provider_id, provider_err);
645 return match parsed {
646 ParsedAPICallError::ContextOverflow {
647 message,
648 response_body,
649 } => MessageError::ContextOverflowError {

Callers 1

processMethod · 0.85

Calls 5

newFunction · 0.85
parse_api_call_errorFunction · 0.85
try_parse_stream_errorFunction · 0.85
containsMethod · 0.80
cloneMethod · 0.45

Tested by

no test coverage detected