fix(console): 修复 workspaces API 在 schema 漂移时的静默 500 - #119
Conversation
|
Warning Review limit reached
Next review available in: 51 minutes You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (8)
📝 WalkthroughWalkthroughChangesSchema drift handling
Estimated code review effort: 2 (Simple) | ~10 minutes Suggested reviewers: 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@internal/platformapi/support.go`:
- Around line 178-186: Update both internalError and internalErrorWithCause in
support.go to use httpapi.WriteError for their 500 responses instead of
writeJSON, preserving the existing message and status while returning the
Anthropic-compatible error envelope. Keep internalErrorWithCause’s slog.Error
logging and request ID handling unchanged.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: ac583313-720f-4560-a916-9b22f57beb6b
📒 Files selected for processing (7)
internal/db/admin_requests.gointernal/db/console_api_keys.gointernal/db/console_invites.gointernal/db/console_members.gointernal/db/postgres_errors.gointernal/platformapi/console_api_keys.gointernal/platformapi/support.go
There was a problem hiding this comment.
DuckPR reviewer: opencode
Model: anthropic/glm-5.2
ℹ️ 没有严重问题 — 行内有几处小建议。
Reviewed changes — 修复 console 工作区 API 在 schema 漂移时返回静默 500:DB 层将 undefined_table / undefined_column 统一降级为空列表,handler 层在 500 前记录原始错误与 request_id。
- 在
internal/db/postgres_errors.go新增isUndefinedRelationError,同时识别 PG 错误码42P01和42703。 - 将 7 处 console 查询(
admin_requests、console_api_keys、console_invites、console_members、console_api_keys.CountConsoleAPIKeys)从isUndefinedTableError切换到isUndefinedRelationError。 - 在
internal/platformapi/support.go新增internalErrorWithCause,先记录错误与request_id再返回 500。 handleListConsoleWorkspaces改用internalErrorWithCause,其余 handler 的internalError调用保持现状。
ℹ️ Nitpicks
- 建议为
isUndefinedRelationError补充单元测试,覆盖42P01/42703/ 其他错误 /nil四种情况;pgconn.PgError可以直接构造,无需真实数据库。
anthropic/glm-5.2 | 𝕏
The console workspace list query selects data_residency from the
workspaces table, but isUndefinedTableError only swallowed PG code
42P01 (undefined_table). A drifted dev database missing the column
surfaced as 42703 (undefined_column), which escaped the guard and
returned 500 from GET /api/console/organizations/{org}/workspaces.
That 500 cascaded through the console workspace context and broke
navigation into memory store detail pages.
- Add isUndefinedRelationError in internal/db/postgres_errors.go
covering both 42P01 and 42703, and switch the seven console list
queries that used isUndefinedTableError to the broader helper.
- Add internalErrorWithCause in internal/platformapi/support.go that
logs the underlying error and request id before responding 500, and
use it in handleListConsoleWorkspaces so future failures stay
diagnosable instead of a bare "failed to list workspaces".
Schema drift now degrades to an empty list with a logged cause,
matching the existing undefined_table behaviour.
- internal/api/server.go: Server 新增 logger 字段,注入到 RegisterConsoleOrganizationWorkspaceRoutes - internal/platformapi/platform_backend_routes.go: 注册函数新增 logger 参数 - internal/platformapi/console_api_keys.go: handleListConsoleWorkspaces 新增 logger 参数并传递给 internalErrorWithCause - internal/platformapi/support.go: internalErrorWithCause 改用参数传入的 logger(nil 时 fallback slog.Default()) - internal/db/postgres_errors.go: isUndefinedRelationError 注释覆盖写操作场景
d107c54 to
3d16dd5
Compare
There was a problem hiding this comment.
DuckPR reviewer: opencode
Model: anthropic/glm-5.2
✅ No new issues found. Both prior nits are addressed cleanly in
3d16dd5.
Reviewed changes — 回应上一轮 review 的两条 nit:将 internalErrorWithCause 的日志改用注入的 logger,并修正 isUndefinedRelationError 的注释范围以覆盖读路径与 RemoveOrgUser 写路径。
- 在
internal/api/server.go为Server新增logger字段(取自ServerDeps.Logger),并在registerPlatformConsoleRoutes中把s.logger透传给RegisterConsoleOrganizationWorkspaceRoutes。 RegisterConsoleOrganizationWorkspaceRoutes与handleListConsoleWorkspaces签名增加logger *slog.Logger,使 workspace 列表 handler 通过internalErrorWithCause使用注入的 logger 记录错误与request_id;仅在调用方未注入时回退slog.Default()。- 修正
isUndefinedRelationError的 doc 注释,明确覆盖 console 查询读路径与RemoveOrgUser这类写路径,不再限定为 list handler。
两处改动均验证通过:logger 链路从 ServerDeps.Logger 到 internalErrorWithCause 完整闭合,go build 通过。
anthropic/glm-5.2 | 𝕏
There was a problem hiding this comment.
DuckPR reviewer: opencode
Model: anthropic/glm-5.2
ℹ️ 合并干净,无新增严重问题 — 行内一处小建议。
Reviewed changes — 本轮将 PR 分支与 origin/main 合并(Yourbatis 迁移、UUID 迁移、slog 标准化等),PR 自身的 schema-drift 兜底逻辑已正确锚定到合并后的新代码结构上。
- 两次 merge commit (
7ec99cf、fede351) 把origin/main的 Yourbatis mapper 迁移、UUID 引用迁移和 slog 标准化(da3b4ed)合入 PR 分支。 ListConsoleAPIKeys/CountConsoleAPIKeys的isUndefinedRelationError守卫已重新锚定到 Yourbatis mapper 路径(mapper.List/mapper.CountUnarchived),旧selectConsoleAPIKeysSQLX调用点随之迁移。internalErrorWithCause的日志已切换为ErrorContext(r.Context(), ...),与合并后的main分支s.logger.ErrorContext用法一致。go build ./internal/platformapi/... ./internal/db/... ./internal/api/...通过,merge 未遗留冲突。
anthropic/glm-5.2 | 𝕏
| if logger == nil { | ||
| logger = slog.Default() | ||
| } | ||
| logger.ErrorContext(r.Context(), message, "err", err, "request_id", httpapi.RequestID(r.Context())) |
There was a problem hiding this comment.
ℹ️ 合并后的 main 分支(da3b4ed slog 标准化)已统一用 "error" 作为错误属性名——internal/ 下所有其他 ErrorContext 调用都是 "error", err,这里是唯一使用 "err" 的地方。建议改为 "error", err 以保持一致,方便日志检索与过滤。
Technical details
# slog field name drift after merge
## Affected sites
- `internal/platformapi/support.go:153` — `logger.ErrorContext(r.Context(), message, "err", err, ...)`
## Required outcome
- 错误值统一用 `"error"` 属性名记录,与 `internal/api/server.go`、`internal/api/platform_mcp_vault_auth.go`、`internal/api/service_auth.go` 等全部 `s.logger.ErrorContext(... "error", err)` 一致。
## Suggested approach
将第 153 行的 `"err", err` 改为 `"error", err`,其余不变。
Fixes #118.
摘要
本地 dev 环境
GET /api/console/organizations/{org}/workspaces在 workspaces 表缺data_residency列(历史 schema 漂移)时返回 500,连锁打挂 console 前端工作空间上下文(memory store 详情页进不去、列表行点击无反应)。本 PR 修复两个根因:isUndefinedTableError只识别 PG42P01(undefined_table),不识别42703(undefined_column)。新增isUndefinedRelationError覆盖两者,7 处 console 列表查询(workspaces / api_keys / invites / members / admin_requests)切到新 helper,让列缺失与表缺失一样降级返回空列表。internalError吞掉原始 err。新增internalErrorWithCause(log err + request_id 再 500),接入handleListConsoleWorkspaces。详见 #118。
改动
internal/db/postgres_errors.go:新增isUndefinedRelationError+ 两个 PG code 常量internal/db/console_api_keys.go:删除旧isUndefinedTableError+ unusedpgconnimport,3 处调用切到新 helperinternal/db/console_invites.go/console_members.go/admin_requests.go:调用切到新 helperinternal/platformapi/support.go:新增internalErrorWithCauseinternal/platformapi/console_api_keys.go:handleListConsoleWorkspaceserr 路径改用internalErrorWithCause验证
go build ./...✅golangci-lint run --config .golangci.yml ./internal/db/... ./internal/platformapi/...✅ 0 issuesjust dead-code✅just duplicates✅just complexity✅go test ./internal/db/... ./internal/platformapi/...✅ALTER TABLE workspaces DROP COLUMN data_residency→ 修复前 500;修复后 200 空列表 + 后端 log 记录 undefined_column设计文档
本次只改错误处理兜底逻辑,不涉及公开 API、数据模型、状态机或架构边界变更。
docs/design/无需更新。不在本 PR 范围
internalError吞 err:internalErrorWithCause已提供入口,后续可逐步推广,不强制本 PR 全改.golangci.yml未排除web/node_modules的 flatted 误报(与本 PR 无关)Summary by CodeRabbit