WIP: M-1 handler sentinel error mapping (checkpoint before branch cleanup)

Uncommitted migration work at the time of branch cleanup. Tagged as
checkpoint/m1-migration-wip so the commit survives git gc --prune=now.

Session context: Phase 3 Part B+C of the M-1 sentinel error migration
was in progress. 38 modified files, 4 new files (errors.go + errors_test.go
in internal/service/ and internal/api/handler/). Resume from this commit
via 'git checkout checkpoint/m1-migration-wip'.
This commit is contained in:
shankar0123
2026-04-24 00:35:12 +00:00
parent d6959a75c1
commit 36e722ba12
42 changed files with 1319 additions and 294 deletions
+23 -7
View File
@@ -1,11 +1,27 @@
package handler
import "errors"
import (
"errors"
"fmt"
var (
// Mock errors for testing
ErrMockServiceFailed = errors.New("mock service error")
ErrMockNotFound = errors.New("mock not found error")
ErrMockUnauthorized = errors.New("mock unauthorized error")
ErrMockConflict = errors.New("mock conflict error")
"github.com/shankar0123/certctl/internal/service"
)
// Mock errors for testing.
//
// M-1: Since the handler layer now classifies errors via the typed-sentinel
// dispatch in [errToStatus] (errors.Is on service + repository sentinels rather
// than substring matching on err.Error()), handler mocks MUST wrap the
// appropriate generic sentinel so `errors.Is(err, service.ErrNotFound)` etc.
// succeed. Using raw errors.New() breaks the dispatch and degrades every
// mock-driven negative-path test to a 500 Internal Server Error — the same
// silent-regression trap the migration was designed to eliminate.
//
// ErrMockServiceFailed deliberately stays untyped so it continues to exercise
// the default 500 path.
var (
ErrMockServiceFailed = errors.New("mock service error")
ErrMockNotFound = fmt.Errorf("%w: mock not found", service.ErrNotFound)
ErrMockUnauthorized = fmt.Errorf("%w: mock unauthenticated", service.ErrUnauthenticated)
ErrMockConflict = fmt.Errorf("%w: mock conflict", service.ErrConflict)
)