Skip to content

refactor(server): centralize db-error-to-HTTP mapping with writeDBError#470

Merged
dlorenc merged 1 commit into
mainfrom
work/kind-raccoon
May 9, 2026
Merged

refactor(server): centralize db-error-to-HTTP mapping with writeDBError#470
dlorenc merged 1 commit into
mainfrom
work/kind-raccoon

Conversation

@dlorenc

@dlorenc dlorenc commented May 9, 2026

Copy link
Copy Markdown
Owner

Summary

  • Add writeDBError(w http.ResponseWriter, op, repo string, err error) to internal/server/errors.go — a single switch over all 23 db sentinel errors mapping each to the correct ErrCode and HTTP status; unrecognised errors log at slog.Error and return 500
  • Replace ~30 repetitive inline switch { case errors.Is(err, db.Err...) } blocks across 11 handler files with single writeDBError(...) calls (net: -344 / +125 lines)
  • For the two handlers with custom JSON conflict bodies (handleMerge, handleRebase) and for handlers with service.ErrForbidden/service.ErrConflict, the special case is handled inline first; writeDBError handles everything else
  • Remove now-unused imports ("errors", "log/slog", db package) from affected files

Error mappings added to writeDBError

Branch: ErrBranchNotFound→404, ErrBranchNotActive→409, ErrBranchExists→409, ErrBranchDraft→409
Repo: ErrRepoNotFound→404, ErrRepoExists→409
Org: ErrOrgNotFound→404, ErrOrgExists→409, ErrOrgHasRepos→409, ErrOrgMemberNotFound→404
Role: ErrRoleNotFound→404
Invite: ErrInviteNotFound→404, ErrInviteExpired→410, ErrInviteAlreadyAccepted→409, ErrEmailMismatch→403
Release: ErrReleaseNotFound→404, ErrReleaseExists→409
Other: ErrSelfApproval→403, ErrCommentNotFound→404, ErrProposalNotFound→404, ErrProposalExists→409, ErrSubscriptionNotFound→404, ErrIssueNotFound→404, ErrIssueCommentNotFound→404

Test plan

  • go build ./... — clean
  • go vet ./... — clean
  • go test ./... -short -count=1 — all 24 packages pass; TestDockerSmoke is excluded by -short and requires GCP credentials (pre-existing infra issue unrelated to this change)

Notes

  • handleDeleteBranch previously returned "branch is already merged or abandoned" for ErrBranchNotActive; writeDBError normalises this to "branch is not active" (matches the db error message and all other call sites)
  • server.go requireRepoReadAccess intentionally left unchanged — it maps ErrRoleNotFound to 403 (access denied), not 404, which is semantically different from writeDBError's mapping
  • Opportunities: the TestDockerSmoke infrastructure issue is worth a separate fix (GCP credentials in CI)

🤖 Generated with Claude Code

Add writeDBError(w, op, repo, err) to internal/server/errors.go with a
single switch covering all 23 db sentinel errors (ErrBranchNotFound,
ErrRepoNotFound, ErrSelfApproval, ErrBranchDraft, ErrOrgNotFound,
ErrInviteExpired, ErrIssueNotFound, etc.). Each case maps to the correct
ErrCode constant and HTTP status, with the default logging at slog.Error
and returning 500.

Replace ~30 repetitive inline switch blocks across 11 handler files with
calls to writeDBError, removing the need to repeat the sentinel→code→status
mapping at each call site. For switches containing non-db cases (service.ErrForbidden,
service.ErrConflict) or custom JSON bodies (ErrMergeConflict, ErrRebaseConflict),
those special cases are handled inline first and the remainder falls through to
writeDBError.

Clean up now-unused imports ("errors", "log/slog", db package) from affected
files.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <[email protected]>
@dlorenc dlorenc merged commit 995f8ad into main May 9, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant