mirror of
https://github.com/router-for-me/CLIProxyAPI.git
synced 2026-02-18 20:30:51 +08:00
Add claude code support
This commit is contained in:
155
internal/auth/claude/errors.go
Normal file
155
internal/auth/claude/errors.go
Normal file
@@ -0,0 +1,155 @@
|
||||
package claude
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
// OAuthError represents an OAuth-specific error
|
||||
type OAuthError struct {
|
||||
Code string `json:"error"`
|
||||
Description string `json:"error_description,omitempty"`
|
||||
URI string `json:"error_uri,omitempty"`
|
||||
StatusCode int `json:"-"`
|
||||
}
|
||||
|
||||
func (e *OAuthError) Error() string {
|
||||
if e.Description != "" {
|
||||
return fmt.Sprintf("OAuth error %s: %s", e.Code, e.Description)
|
||||
}
|
||||
return fmt.Sprintf("OAuth error: %s", e.Code)
|
||||
}
|
||||
|
||||
// NewOAuthError creates a new OAuth error
|
||||
func NewOAuthError(code, description string, statusCode int) *OAuthError {
|
||||
return &OAuthError{
|
||||
Code: code,
|
||||
Description: description,
|
||||
StatusCode: statusCode,
|
||||
}
|
||||
}
|
||||
|
||||
// AuthenticationError represents authentication-related errors
|
||||
type AuthenticationError struct {
|
||||
Type string `json:"type"`
|
||||
Message string `json:"message"`
|
||||
Code int `json:"code"`
|
||||
Cause error `json:"-"`
|
||||
}
|
||||
|
||||
func (e *AuthenticationError) Error() string {
|
||||
if e.Cause != nil {
|
||||
return fmt.Sprintf("%s: %s (caused by: %v)", e.Type, e.Message, e.Cause)
|
||||
}
|
||||
return fmt.Sprintf("%s: %s", e.Type, e.Message)
|
||||
}
|
||||
|
||||
// Common authentication error types
|
||||
var (
|
||||
ErrTokenExpired = &AuthenticationError{
|
||||
Type: "token_expired",
|
||||
Message: "Access token has expired",
|
||||
Code: http.StatusUnauthorized,
|
||||
}
|
||||
|
||||
ErrInvalidState = &AuthenticationError{
|
||||
Type: "invalid_state",
|
||||
Message: "OAuth state parameter is invalid",
|
||||
Code: http.StatusBadRequest,
|
||||
}
|
||||
|
||||
ErrCodeExchangeFailed = &AuthenticationError{
|
||||
Type: "code_exchange_failed",
|
||||
Message: "Failed to exchange authorization code for tokens",
|
||||
Code: http.StatusBadRequest,
|
||||
}
|
||||
|
||||
ErrServerStartFailed = &AuthenticationError{
|
||||
Type: "server_start_failed",
|
||||
Message: "Failed to start OAuth callback server",
|
||||
Code: http.StatusInternalServerError,
|
||||
}
|
||||
|
||||
ErrPortInUse = &AuthenticationError{
|
||||
Type: "port_in_use",
|
||||
Message: "OAuth callback port is already in use",
|
||||
Code: 13, // Special exit code for port-in-use
|
||||
}
|
||||
|
||||
ErrCallbackTimeout = &AuthenticationError{
|
||||
Type: "callback_timeout",
|
||||
Message: "Timeout waiting for OAuth callback",
|
||||
Code: http.StatusRequestTimeout,
|
||||
}
|
||||
|
||||
ErrBrowserOpenFailed = &AuthenticationError{
|
||||
Type: "browser_open_failed",
|
||||
Message: "Failed to open browser for authentication",
|
||||
Code: http.StatusInternalServerError,
|
||||
}
|
||||
)
|
||||
|
||||
// NewAuthenticationError creates a new authentication error with a cause
|
||||
func NewAuthenticationError(baseErr *AuthenticationError, cause error) *AuthenticationError {
|
||||
return &AuthenticationError{
|
||||
Type: baseErr.Type,
|
||||
Message: baseErr.Message,
|
||||
Code: baseErr.Code,
|
||||
Cause: cause,
|
||||
}
|
||||
}
|
||||
|
||||
// IsAuthenticationError checks if an error is an authentication error
|
||||
func IsAuthenticationError(err error) bool {
|
||||
var authenticationError *AuthenticationError
|
||||
ok := errors.As(err, &authenticationError)
|
||||
return ok
|
||||
}
|
||||
|
||||
// IsOAuthError checks if an error is an OAuth error
|
||||
func IsOAuthError(err error) bool {
|
||||
var oAuthError *OAuthError
|
||||
ok := errors.As(err, &oAuthError)
|
||||
return ok
|
||||
}
|
||||
|
||||
// GetUserFriendlyMessage returns a user-friendly error message
|
||||
func GetUserFriendlyMessage(err error) string {
|
||||
switch {
|
||||
case IsAuthenticationError(err):
|
||||
var authErr *AuthenticationError
|
||||
errors.As(err, &authErr)
|
||||
switch authErr.Type {
|
||||
case "token_expired":
|
||||
return "Your authentication has expired. Please log in again."
|
||||
case "token_invalid":
|
||||
return "Your authentication is invalid. Please log in again."
|
||||
case "authentication_required":
|
||||
return "Please log in to continue."
|
||||
case "port_in_use":
|
||||
return "The required port is already in use. Please close any applications using port 3000 and try again."
|
||||
case "callback_timeout":
|
||||
return "Authentication timed out. Please try again."
|
||||
case "browser_open_failed":
|
||||
return "Could not open your browser automatically. Please copy and paste the URL manually."
|
||||
default:
|
||||
return "Authentication failed. Please try again."
|
||||
}
|
||||
case IsOAuthError(err):
|
||||
var oauthErr *OAuthError
|
||||
errors.As(err, &oauthErr)
|
||||
switch oauthErr.Code {
|
||||
case "access_denied":
|
||||
return "Authentication was cancelled or denied."
|
||||
case "invalid_request":
|
||||
return "Invalid authentication request. Please try again."
|
||||
case "server_error":
|
||||
return "Authentication server error. Please try again later."
|
||||
default:
|
||||
return fmt.Sprintf("Authentication failed: %s", oauthErr.Description)
|
||||
}
|
||||
default:
|
||||
return "An unexpected error occurred. Please try again."
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user