From fd51ff697092bf1948c987de97b4d1be1c1bf591 Mon Sep 17 00:00:00 2001 From: yangjianbo Date: Sun, 28 Dec 2025 14:34:05 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BB=A3=E7=A0=81=E7=9A=84=E6=A0=B8?= =?UTF-8?q?=E5=BF=83=E9=97=AE=E9=A2=98=E6=98=AF=E5=88=A4=E9=94=99=E6=9D=A1?= =?UTF-8?q?=E4=BB=B6=E7=94=A8=E9=94=99=E4=BA=86=E5=B1=82=E7=BA=A7=EF=BC=9A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - apiKeyService.GetByKey(...) 返回的“找不到 API key”在这个项目里通常会被翻译成业务错误(比如 service.ErrApiKeyNotFound 这类 ApplicationError),而不是直接把 gorm.ErrRecordNotFound 透传到中 间件层。 - 因此你在中间件里用 errors.Is(err, gorm.ErrRecordNotFound) 去判断“无效 key”,很容易匹配不到(尤其 是:后面加 Redis 缓存、换存储实现、或测试里用 stub repo 时,根本不会出现 gorm 的错误)。 - 匹配不到时就会走到 500 Failed to validate API key,导致无效 API key 被错误地当成服务端故障返回 500(应该是 401)。 修复思路:中间件不要依赖 gorm 的错误,改成判断业务层错误,例如: if errors.Is(err, service.ErrApiKeyNotFound) { abortWithGoogleError(c, 401, "Invalid API key") return } 如果你把 GetByKey 的“not found”统一封装成业务错误,这样才不会被底层实现(gorm/redis/mock)影响。 --- backend/internal/server/middleware/api_key_auth_google.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/backend/internal/server/middleware/api_key_auth_google.go b/backend/internal/server/middleware/api_key_auth_google.go index e37b389e..199aca82 100644 --- a/backend/internal/server/middleware/api_key_auth_google.go +++ b/backend/internal/server/middleware/api_key_auth_google.go @@ -8,7 +8,6 @@ import ( "github.com/Wei-Shaw/sub2api/internal/service" "github.com/gin-gonic/gin" - "gorm.io/gorm" ) // ApiKeyAuthGoogle is a Google-style error wrapper for API key auth. @@ -30,7 +29,7 @@ func ApiKeyAuthWithSubscriptionGoogle(apiKeyService *service.ApiKeyService, subs apiKey, err := apiKeyService.GetByKey(c.Request.Context(), apiKeyString) if err != nil { - if errors.Is(err, gorm.ErrRecordNotFound) { + if errors.Is(err, service.ErrApiKeyNotFound) { abortWithGoogleError(c, 401, "Invalid API key") return }