error.go 1.38 KB
package domain

import (
	"errors"
	"fmt"
)

type ErrorCode struct {
	slug string
}

func (e ErrorCode) String() string {
	return e.slug
}

var (
	Unknown      = ErrorCode{"unknown"}
	NotFound     = ErrorCode{"not_found"}
	Validation   = ErrorCode{"validation_error"}
	Database     = ErrorCode{"database_error"}
	InactiveUser = ErrorCode{"user_inactive"}
)

func FromString(s string) (ErrorCode, error) {
	switch s {
	case NotFound.slug:
		return NotFound, nil
	case Validation.slug:
		return Validation, nil
	case Database.slug:
		return Database, nil
	case InactiveUser.slug:
		return InactiveUser, nil
	}
	return Unknown, errors.New("unknown error code: " + s)
}

type Error struct {
	Code    ErrorCode
	Message string
	Err     error
}

func (e *Error) Error() string {
	if e.Err != nil {
		return fmt.Sprintf("%s: %v", e.Message, e.Err)
	}
	return e.Message
}

func (e *Error) Unwrap() error {
	return e.Err
}

var (
	ErrNotFound = &Error{
		Code:    NotFound,
		Message: "resource not found",
	}
	ErrValidation = &Error{
		Code:    Validation,
		Message: "validation failed",
	}
	ErrDatabase = &Error{
		Code:    Database,
		Message: "database operation failed",
	}
	ErrInactiveUser = &Error{
		Code:    InactiveUser,
		Message: "user account is inactive",
	}
)

func NewError(code ErrorCode, message string, err error) *Error {
	return &Error{
		Code:    code,
		Message: message,
		Err:     err,
	}
}