auth: preserve ensure error after retry exhaustion

This commit is contained in:
CJACK.
2026-04-02 12:58:09 +08:00
parent f6cd541c6f
commit e60738b084
2 changed files with 38 additions and 0 deletions

View File

@@ -79,12 +79,19 @@ func (r *Resolver) Determine(req *http.Request) (*RequestAuth, error) {
func (r *Resolver) acquireManagedRequestAuth(ctx context.Context, callerID, target string) (*RequestAuth, error) {
tried := map[string]bool{}
var lastEnsureErr error
for {
if target == "" && len(tried) >= len(r.Store.Accounts()) {
if lastEnsureErr != nil {
return nil, lastEnsureErr
}
return nil, ErrNoAccount
}
acc, ok := r.Pool.AcquireWait(ctx, target, tried)
if !ok {
if lastEnsureErr != nil {
return nil, lastEnsureErr
}
return nil, ErrNoAccount
}
@@ -98,6 +105,7 @@ func (r *Resolver) acquireManagedRequestAuth(ctx context.Context, callerID, targ
}
if err := r.ensureManagedToken(ctx, a); err != nil {
lastEnsureErr = err
tried[a.AccountID] = true
r.Pool.Release(a.AccountID)
if target != "" {

View File

@@ -365,3 +365,33 @@ func TestDetermineTargetAccountDoesNotFallbackOnLoginFailure(t *testing.T) {
t.Fatal("expected determine to fail for broken target account")
}
}
func TestDetermineManagedAccountReturnsLastEnsureErrorWhenAllFail(t *testing.T) {
t.Setenv("DS2API_CONFIG_JSON", `{
"keys":["managed-key"],
"accounts":[
{"email":"bad1@example.com","password":"pwd"},
{"email":"bad2@example.com","password":"pwd"}
]
}`)
store := config.LoadStore()
pool := account.NewPool(store)
ensureErr := errors.New("all credentials stale")
resolver := NewResolver(store, pool, func(_ context.Context, _ config.Account) (string, error) {
return "", ensureErr
})
req, _ := http.NewRequest(http.MethodPost, "/v1/chat/completions", nil)
req.Header.Set("x-api-key", "managed-key")
_, err := resolver.Determine(req)
if err == nil {
t.Fatal("expected determine to fail")
}
if !errors.Is(err, ensureErr) {
t.Fatalf("expected ensure error, got %v", err)
}
if errors.Is(err, ErrNoAccount) {
t.Fatalf("expected auth-style ensure error, got ErrNoAccount")
}
}