apperrors

package
v1.0.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 20, 2026 License: MIT Imports: 2 Imported by: 0

Documentation

Overview

Package apperrors provides typed domain errors with HTTP status mapping.

Domain errors are defined in the domain layer without any HTTP knowledge. The server middleware maps AppError types to HTTP status codes automatically.

Usage in domain layer:

var ErrUserNotFound = apperrors.NotFound("user not found")
var ErrEmailTaken   = apperrors.Conflict("email already taken")

Usage in server middleware:

status := apperrors.HTTPStatus(err)  // 404, 409, etc.

Package apperrors provides typed domain errors with HTTP status mapping.

Overview

Define errors in the domain layer without any HTTP knowledge. The server middleware maps AppError types to HTTP status codes automatically.

Defining domain errors

package users

import "github.com/miilkaa/portsmith/pkg/apperrors"

var (
    ErrUserNotFound = apperrors.NotFound("user not found")
    ErrEmailTaken   = apperrors.Conflict("email already taken")
)

Error comparison

Use errors.Is for sentinel error comparison — it works across error chains:

if errors.Is(err, users.ErrUserNotFound) { ... }

HTTP mapping

The server error middleware calls apperrors.HTTPStatus automatically. Explicit use is rarely needed:

status := apperrors.HTTPStatus(err)  // 404, 409, 400, 403, 401, 500

Error codes

CodeNotFound     → 404
CodeConflict     → 409
CodeBadRequest   → 400
CodeForbidden    → 403
CodeUnauthorized → 401
CodeInternal     → 500

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func As

func As(err error, target **AppError) bool

As is a convenience wrapper around errors.As for *AppError.

func HTTPStatus

func HTTPStatus(err error) int

HTTPStatus maps an AppError code to the corresponding HTTP status code. Returns 500 for any unrecognised code or non-AppError errors.

func IsAppError

func IsAppError(err error) bool

IsAppError reports whether err is an *AppError.

func IsCode

func IsCode(err error, code Code) bool

IsCode reports whether err is an *AppError with the given code.

Types

type AppError

type AppError struct {
	// contains filtered or unexported fields
}

AppError is a typed domain error with an associated code and optional details. Use errors.Is for sentinel error comparison.

func BadRequest

func BadRequest(msg string) *AppError

BadRequest creates a BAD_REQUEST domain error (maps to HTTP 400).

func Conflict

func Conflict(msg string) *AppError

Conflict creates a CONFLICT domain error (maps to HTTP 409).

func Forbidden

func Forbidden(msg string) *AppError

Forbidden creates a FORBIDDEN domain error (maps to HTTP 403).

func Internal

func Internal(msg string, args ...any) *AppError

Internal creates an INTERNAL domain error (maps to HTTP 500).

func NotFound

func NotFound(msg string) *AppError

NotFound creates a NOT_FOUND domain error (maps to HTTP 404).

func Unauthorized

func Unauthorized(msg string) *AppError

Unauthorized creates an UNAUTHORIZED domain error (maps to HTTP 401).

func WithDetails

func WithDetails(err *AppError, details map[string]any) *AppError

WithDetails returns a copy of the AppError enriched with structured details. The resulting error still matches the original via errors.Is.

func (*AppError) Code

func (e *AppError) Code() Code

Code returns the error classification code.

func (*AppError) Details

func (e *AppError) Details() map[string]any

Details returns optional structured error details (e.g. validation field errors).

func (*AppError) Error

func (e *AppError) Error() string

Error implements the error interface.

func (*AppError) Is

func (e *AppError) Is(target error) bool

Is enables errors.Is comparison for sentinel errors. Two AppErrors are equal when both their code and message match.

type Code

type Code string

Code represents the type of application error.

const (
	CodeNotFound     Code = "NOT_FOUND"
	CodeConflict     Code = "CONFLICT"
	CodeBadRequest   Code = "BAD_REQUEST"
	CodeForbidden    Code = "FORBIDDEN"
	CodeUnauthorized Code = "UNAUTHORIZED"
	CodeInternal     Code = "INTERNAL"
)

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL