Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Menu
Open sidebar
陈曦
sub2api
Commits
ce8520c9
"backend/cmd/git@web.lueluesay.top:chenxi/sub2api.git" did not exist on "e2ae9fe50bce3ae1761cbef19d55ea900d27ed31"
Commit
ce8520c9
authored
Mar 24, 2026
by
qingyuzhang
Browse files
fix(openai): persist passthrough 429 rate limits
parent
bda7c39e
Changes
2
Hide whitespace changes
Inline
Side-by-side
backend/internal/service/openai_gateway_service.go
View file @
ce8520c9
...
...
@@ -2598,6 +2598,12 @@ func (s *OpenAIGatewayService) handleErrorResponsePassthrough(
}
setOpsUpstreamError
(
c
,
resp
.
StatusCode
,
upstreamMsg
,
upstreamDetail
)
logOpenAIInstructionsRequiredDebug
(
ctx
,
c
,
account
,
resp
.
StatusCode
,
upstreamMsg
,
requestBody
,
body
)
if
s
.
rateLimitService
!=
nil
{
// Passthrough mode preserves the raw upstream error response, but runtime
// account state still needs to be updated so sticky routing can stop
// reusing a freshly rate-limited account.
_
=
s
.
rateLimitService
.
HandleUpstreamError
(
ctx
,
account
,
resp
.
StatusCode
,
resp
.
Header
,
body
)
}
appendOpsUpstreamError
(
c
,
OpsUpstreamErrorEvent
{
Platform
:
account
.
Platform
,
AccountID
:
account
.
ID
,
...
...
backend/internal/service/openai_oauth_passthrough_test.go
View file @
ce8520c9
...
...
@@ -536,6 +536,55 @@ func TestOpenAIGatewayService_OAuthPassthrough_UpstreamErrorIncludesPassthroughF
require
.
True
(
t
,
arr
[
len
(
arr
)
-
1
]
.
Passthrough
)
}
func
TestOpenAIGatewayService_OAuthPassthrough_429PersistsRateLimit
(
t
*
testing
.
T
)
{
gin
.
SetMode
(
gin
.
TestMode
)
rec
:=
httptest
.
NewRecorder
()
c
,
_
:=
gin
.
CreateTestContext
(
rec
)
c
.
Request
=
httptest
.
NewRequest
(
http
.
MethodPost
,
"/v1/responses"
,
bytes
.
NewReader
(
nil
))
c
.
Request
.
Header
.
Set
(
"User-Agent"
,
"codex_cli_rs/0.1.0"
)
originalBody
:=
[]
byte
(
`{"model":"gpt-5.2","stream":false,"instructions":"local-test-instructions","input":[{"type":"text","text":"hi"}]}`
)
resetAt
:=
time
.
Now
()
.
Add
(
7
*
24
*
time
.
Hour
)
.
Unix
()
resp
:=
&
http
.
Response
{
StatusCode
:
http
.
StatusTooManyRequests
,
Header
:
http
.
Header
{
"Content-Type"
:
[]
string
{
"application/json"
},
"x-request-id"
:
[]
string
{
"rid-rate-limit"
},
},
Body
:
io
.
NopCloser
(
strings
.
NewReader
(
fmt
.
Sprintf
(
`{"error":{"message":"The usage limit has been reached","type":"usage_limit_reached","resets_at":%d}}`
,
resetAt
))),
}
upstream
:=
&
httpUpstreamRecorder
{
resp
:
resp
}
repo
:=
&
openAIWSRateLimitSignalRepo
{}
rateSvc
:=
&
RateLimitService
{
accountRepo
:
repo
}
svc
:=
&
OpenAIGatewayService
{
cfg
:
&
config
.
Config
{
Gateway
:
config
.
GatewayConfig
{
ForceCodexCLI
:
false
}},
httpUpstream
:
upstream
,
rateLimitService
:
rateSvc
,
}
account
:=
&
Account
{
ID
:
123
,
Name
:
"acc"
,
Platform
:
PlatformOpenAI
,
Type
:
AccountTypeOAuth
,
Concurrency
:
1
,
Credentials
:
map
[
string
]
any
{
"access_token"
:
"oauth-token"
,
"chatgpt_account_id"
:
"chatgpt-acc"
},
Extra
:
map
[
string
]
any
{
"openai_passthrough"
:
true
},
Status
:
StatusActive
,
Schedulable
:
true
,
RateMultiplier
:
f64p
(
1
),
}
_
,
err
:=
svc
.
Forward
(
context
.
Background
(),
c
,
account
,
originalBody
)
require
.
Error
(
t
,
err
)
require
.
Equal
(
t
,
http
.
StatusTooManyRequests
,
rec
.
Code
)
require
.
Contains
(
t
,
rec
.
Body
.
String
(),
"usage_limit_reached"
)
require
.
Len
(
t
,
repo
.
rateLimitCalls
,
1
)
require
.
WithinDuration
(
t
,
time
.
Unix
(
resetAt
,
0
),
repo
.
rateLimitCalls
[
0
],
2
*
time
.
Second
)
}
func
TestOpenAIGatewayService_OAuthPassthrough_NonCodexUAFallbackToCodexUA
(
t
*
testing
.
T
)
{
gin
.
SetMode
(
gin
.
TestMode
)
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment