yoi/crates/provider/src/codex_oauth/error.rs

75 lines
2.4 KiB
Rust
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//! Codex OAuth サブモジュール内部のエラー型。
//!
//! `LlmClient` 境界に渡す際は `to_client_error` で `ClientError` に
//! 変換する。`Permanent` 系refresh_token 失効)は `codex login` の
//! 再実行案内付きメッセージにする。
use std::path::PathBuf;
use llm_worker::llm_client::ClientError;
use thiserror::Error;
#[derive(Debug, Error)]
pub enum CodexAuthError {
#[error(
"not logged in to ChatGPT: {0} not found. Run `codex login` and ensure cli_auth_credentials_store = \"file\"."
)]
NotLoggedIn(PathBuf),
#[error("malformed ~/.codex/auth.json: {0}")]
MalformedAuthJson(String),
#[error("io error: {0}")]
Io(String),
#[error("token refresh failed (transient): {0}")]
RefreshTransient(String),
/// refresh_token が永続的に失効。再ログインが必要。
#[error("token refresh failed permanently ({reason:?}): {message}")]
RefreshPermanent {
reason: PermanentReason,
message: String,
},
#[error("invalid header value: {0}")]
InvalidHeader(String),
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum PermanentReason {
Expired,
Reused,
Revoked,
Other,
}
impl CodexAuthError {
/// `LlmClient` トランスポート境界向けに変換する。
pub fn to_client_error(self) -> ClientError {
match self {
CodexAuthError::NotLoggedIn(_)
| CodexAuthError::MalformedAuthJson(_)
| CodexAuthError::Io(_)
| CodexAuthError::InvalidHeader(_) => ClientError::Config(self.to_string()),
CodexAuthError::RefreshTransient(msg) => ClientError::Api {
status: None,
code: Some("refresh_transient".into()),
message: msg,
retry_after: None,
},
CodexAuthError::RefreshPermanent { reason, message } => ClientError::Api {
status: Some(401),
code: Some(match reason {
PermanentReason::Expired => "refresh_token_expired".into(),
PermanentReason::Reused => "refresh_token_reused".into(),
PermanentReason::Revoked => "refresh_token_invalidated".into(),
PermanentReason::Other => "refresh_token_failed".into(),
}),
message: format!("{message}. Please run `codex login` again."),
retry_after: None,
},
}
}
}