Line data Source code
1 : // Package shared contains usecase-wide helpers for error normalization.
2 : // It centralizes translation from infra-layer errors into application errors,
3 : // and provides convenience helpers for common cases (e.g., not-found on nil).
4 : package shared
5 :
6 : import (
7 : "strings"
8 :
9 : "resume/internal/shared/apperr"
10 : )
11 :
12 : // ErrBadRequest should be used for transport-level issues detected in handlers
13 : // (JSON decode failure, missing keys at payload level, type mismatches).
14 : var ErrBadRequest = apperr.New(apperr.CodeBadRequest, "bad request", nil)
15 :
16 : // ErrUnprocessable should be used for validation failures in handlers or usecases
17 : // where the payload is syntactically valid but violates field/business rules.
18 : var ErrUnprocessable = apperr.New(apperr.CodeUnprocessable, "validation failed", nil)
19 :
20 : // MapInfraError normalizes infra-layer errors (db/driver/SDK) into application errors.
21 : // NOTE: This version uses string heuristics as a stopgap.
22 : // In production, prefer repository-defined sentinels and errors.Is checks.
23 0 : func MapInfraError(err error) error {
24 0 : if err == nil {
25 0 : return nil
26 0 : }
27 0 : msg := strings.ToLower(err.Error())
28 0 : switch {
29 0 : case strings.Contains(msg, "duplicate"), strings.Contains(msg, "unique"):
30 0 : return apperr.Wrap(apperr.CodeConflict, "resource already exists", err, nil)
31 0 : case strings.Contains(msg, "not found"), strings.Contains(msg, "record not found"):
32 0 : return apperr.Wrap(apperr.CodeNotFound, "resource not found", err, nil)
33 0 : default:
34 0 : return apperr.Wrap(apperr.CodeInternal, "internal error", err, nil)
35 : }
36 : }
37 :
38 : // NotFoundIfNil turns a nil pointer result into a NOT_FOUND application error.
39 : // Useful for "findOne" style usecases to keep the calling code simple.
40 0 : func NotFoundIfNil[T any](v *T, what string) (*T, error) {
41 0 : if v == nil {
42 0 : return nil, apperr.New(apperr.CodeNotFound, what+" not found", nil)
43 0 : }
44 0 : return v, nil
45 : }
|