Summary
PR #100 introduced ActionResult<T> discriminated union type and converted github.ts and user-presets.ts. The remaining Server Action files should be incrementally migrated to this pattern.
Why ActionResult
- Discriminated unions (
{ success: true; data: T } | { success: false; error: string }) provide compile-time safety that { data: T | null; error: string | null } cannot. TypeScript narrows the type after checking result.success, so you can safely access result.data or result.error without null checks.
withAuthResult<T> wraps the try/catch + Sentry reporting in one place, so every server action gets consistent error handling for free. The auth check returns a result object instead of throwing, which means callers never need try/catch for auth failures.
Remaining Files
board.ts (client-consumed functions)
createBoard — called from CreateBoardForm.tsx (currently throws)
updateBoardPositions — called from BoardGrid.tsx (currently throws)
shared-project-info.ts → project-info.ts / maintenance-project-info.ts
upsertProjectInfoCore → wrapper upsertProjectInfo (currently throws)
updateCommentCore → wrapper updateComment (currently throws)
updateCommentColorCore → wrapper updateCommentColor (currently throws)
deleteCommentCore → wrapper deleteComment (currently throws)
getProjectInfoCore → wrapper getProjectInfo (currently throws on DB error)
repo-cards.ts (type alignment only)
- Already uses
{ success, error } pattern — just add ActionResult<T> return type annotations
Scope
- DO NOT convert internal/server-component-only functions (e.g.,
getStatusLists, getBoardData, fetchBoardInitialData) — these can stay throw-based since server components have error boundaries
- DO NOT convert
auth.ts — uses redirect(), special flow
- DO NOT convert useActionState functions — they have specific state shapes required by the hook
Source
Established pattern in PR #100 (refactor/error-handling-68), src/lib/actions/types.ts
Summary
PR #100 introduced
ActionResult<T>discriminated union type and convertedgithub.tsanduser-presets.ts. The remaining Server Action files should be incrementally migrated to this pattern.Why ActionResult
{ success: true; data: T } | { success: false; error: string }) provide compile-time safety that{ data: T | null; error: string | null }cannot. TypeScript narrows the type after checkingresult.success, so you can safely accessresult.dataorresult.errorwithout null checks.withAuthResult<T>wraps the try/catch + Sentry reporting in one place, so every server action gets consistent error handling for free. The auth check returns a result object instead of throwing, which means callers never need try/catch for auth failures.Remaining Files
board.ts (client-consumed functions)
createBoard— called fromCreateBoardForm.tsx(currently throws)updateBoardPositions— called fromBoardGrid.tsx(currently throws)shared-project-info.ts → project-info.ts / maintenance-project-info.ts
upsertProjectInfoCore→ wrapperupsertProjectInfo(currently throws)updateCommentCore→ wrapperupdateComment(currently throws)updateCommentColorCore→ wrapperupdateCommentColor(currently throws)deleteCommentCore→ wrapperdeleteComment(currently throws)getProjectInfoCore→ wrappergetProjectInfo(currently throws on DB error)repo-cards.ts (type alignment only)
{ success, error }pattern — just addActionResult<T>return type annotationsScope
getStatusLists,getBoardData,fetchBoardInitialData) — these can stay throw-based since server components have error boundariesauth.ts— usesredirect(), special flowSource
Established pattern in PR #100 (
refactor/error-handling-68),src/lib/actions/types.ts