package domain import ( "errors" "fmt" "github.com/gosimple/slug" ) type ErrorCode uint8 const ( ErrorCodeUnknown ErrorCode = iota ErrorCodeEntityNotFound ErrorCodeIncorrectInput ) func (e ErrorCode) String() string { switch e { case ErrorCodeEntityNotFound: return "entity-not-found" case ErrorCodeIncorrectInput: return "incorrect-input" case ErrorCodeUnknown: fallthrough default: return "unknown-error" } } type Error interface { error Code() ErrorCode Slug() string } type ErrorWithParams interface { Error Params() map[string]any } type ValidationError struct { Field string Err error } var _ ErrorWithParams = ValidationError{} func (e ValidationError) Error() string { return fmt.Sprintf("%s: %s", e.Field, e.Err) } func (e ValidationError) Code() ErrorCode { var domainErr Error if errors.As(e.Err, &domainErr) { return domainErr.Code() } return ErrorCodeIncorrectInput } func (e ValidationError) Slug() string { s := "validation" var domainErr Error if errors.As(e.Err, &domainErr) { s = domainErr.Slug() } return fmt.Sprintf("%s-%s", slug.Make(e.Field), s) } func (e ValidationError) Params() map[string]any { var withParams ErrorWithParams ok := errors.As(e.Err, &withParams) if !ok { return nil } return withParams.Params() }