package model import ( "errors" "fmt" "net/http" ) var ( ErrNotFound = errors.New("resource not found") ErrDuplicate = errors.New("resource already exists") ErrUnauthorized = errors.New("unauthorized") ErrForbidden = errors.New("forbidden") ) // AppError is a service-layer error that carries an HTTP status, a user-safe // message, and an optional internal cause for logging. Handlers unpack it // transparently via api.RespondError. type AppError struct { Status int // HTTP status code Message string // safe for API response Err error // internal cause (nil = user-caused, skip logging) } func (e *AppError) Error() string { return e.Message } func (e *AppError) Unwrap() error { return e.Err } // NewInternalError creates a 500 AppError with a wrapped internal cause. // msg describes the operation that failed; cause is the underlying error. func NewInternalError(msg string, cause error) *AppError { return &AppError{ Status: http.StatusInternalServerError, Message: "internal server error", Err: fmt.Errorf("%s: %w", msg, cause), } }