Merge pull request #1829 from ZHOUKAILIAN/feature/codex-oauth-proxy-message

fix: 明确 OpenAI OAuth 未配置代理时的错误提示
This commit is contained in:
Wesley Liddick
2026-04-23 16:55:04 +08:00
committed by GitHub
6 changed files with 99 additions and 3 deletions

View File

@@ -2,6 +2,7 @@ package repository
import (
"context"
"errors"
"net/http"
"net/url"
"strings"
@@ -53,6 +54,9 @@ func (s *openaiOAuthService) ExchangeCode(ctx context.Context, code, codeVerifie
Post(s.tokenURL)
if err != nil {
if shouldReturnOpenAINoProxyHint(ctx, proxyURL, err) {
return nil, newOpenAINoProxyHintError(err)
}
return nil, infraerrors.Newf(http.StatusBadGateway, "OPENAI_OAUTH_REQUEST_FAILED", "request failed: %v", err)
}
@@ -98,6 +102,9 @@ func (s *openaiOAuthService) refreshTokenWithClientID(ctx context.Context, refre
Post(s.tokenURL)
if err != nil {
if shouldReturnOpenAINoProxyHint(ctx, proxyURL, err) {
return nil, newOpenAINoProxyHintError(err)
}
return nil, infraerrors.Newf(http.StatusBadGateway, "OPENAI_OAUTH_REQUEST_FAILED", "request failed: %v", err)
}
@@ -114,3 +121,21 @@ func createOpenAIReqClient(proxyURL string) (*req.Client, error) {
Timeout: 120 * time.Second,
})
}
func shouldReturnOpenAINoProxyHint(ctx context.Context, proxyURL string, err error) bool {
if strings.TrimSpace(proxyURL) != "" || err == nil {
return false
}
if ctx != nil && ctx.Err() != nil {
return false
}
return !errors.Is(err, context.Canceled)
}
func newOpenAINoProxyHintError(cause error) error {
return infraerrors.New(
http.StatusBadGateway,
"OPENAI_OAUTH_PROXY_REQUIRED",
"OpenAI OAuth request failed: no proxy is configured and this server could not reach OpenAI directly. Select a proxy that can access OpenAI, then retry; if the authorization code has expired, regenerate the authorization URL.",
).WithCause(cause)
}

View File

@@ -8,6 +8,7 @@ import (
"net/url"
"testing"
infraerrors "github.com/Wei-Shaw/sub2api/internal/pkg/errors"
"github.com/Wei-Shaw/sub2api/internal/pkg/openai"
"github.com/stretchr/testify/require"
"github.com/stretchr/testify/suite"
@@ -204,6 +205,17 @@ func (s *OpenAIOAuthServiceSuite) TestRequestError_ClosedServer() {
require.ErrorContains(s.T(), err, "request failed")
}
func (s *OpenAIOAuthServiceSuite) TestExchangeCode_RequestErrorWithoutProxyReturnsProxyHint() {
s.setupServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {}))
s.srv.Close()
_, err := s.svc.ExchangeCode(s.ctx, "code", "ver", openai.DefaultRedirectURI, "", "")
require.Error(s.T(), err)
require.Equal(s.T(), "OPENAI_OAUTH_PROXY_REQUIRED", infraerrors.Reason(err))
require.Contains(s.T(), infraerrors.Message(err), "no proxy is configured")
}
func (s *OpenAIOAuthServiceSuite) TestContextCancel() {
started := make(chan struct{})
block := make(chan struct{})