package domain import "fmt" type ErrorCode uint8 const ( ErrorCodeUnknown ErrorCode = iota ErrorCodeValidation ErrorCodeIO // External I/O error such as network failure. ) func (e ErrorCode) String() string { switch e { case ErrorCodeValidation: return "validation-error" case ErrorCodeIO: return "io-error" case ErrorCodeUnknown: fallthrough default: return "internal-server-error" } } type Error struct { code ErrorCode msg string err error } type ErrorOption func(err Error) Error func WithCode(code ErrorCode) ErrorOption { return func(err Error) Error { err.code = code return err } } func WithErr(wrap error) ErrorOption { return func(err Error) Error { err.err = wrap return err } } func WithMessage(msg string) ErrorOption { return func(err Error) Error { err.msg = msg return err } } func WithMessagef(format string, a ...any) ErrorOption { return func(err Error) Error { err.msg = fmt.Sprintf(format, a...) return err } } func NewError(opts ...ErrorOption) Error { var err Error for _, opt := range opts { err = opt(err) } return err } func (err Error) Error() string { if err.err != nil { return err.msg + ": " + err.err.Error() } return err.msg } func (err Error) Message() string { return err.msg } func (err Error) Code() ErrorCode { return err.code } func (err Error) Unwrap() error { return err.err }