Something went wrong. Try again.
Read-only ActivityPub → atproto bridge for the threadiverse using Coves lexicons
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127// Package errors provides sentinel and typed errors shared across Tidepool.// It mirrors the Coves error conventions: sentinel values for errors.Is// checks, small typed errors carrying context, and helpers for the common// classification questions. Typed errors unwrap to their matching sentinel,// so errors.Is(err, ErrNotFound) works on a NotFoundError and anything// wrapping one with %w.package errors
import ( "errors" "fmt")
var ( ErrNotFound = errors.New("resource not found") ErrAlreadyExists = errors.New("resource already exists") ErrInvalidInput = errors.New("invalid input") // ErrTombstoned marks a resource that existed but was soft-deleted // (AP Delete / Tombstone). It is deliberately distinct from ErrNotFound: // a missing object may be fetched and materialized, a tombstoned one // must not be. IsNotFound(tombstoned) is false. ErrTombstoned = errors.New("resource tombstoned") // ErrRecordGone marks a bridged-stats emission that cannot proceed // because the TARGET RECORD itself is gone — deleted out from under its // vote aggregate, or its mapping soft-deleted inside the commit // transaction. Deliberately distinct from ErrNotFound: the vote-stats // refresher advances its watermark on a real record-gone but NOT on an // unrelated NotFound surfaced from deeper in a commit (a missing // bridged_actor row or signing key — a key-escrow inconsistency to // retry, never to skip). IsNotFound(recordGone) is false. ErrRecordGone = errors.New("bridged record gone") // ErrCollectionImmutable marks a mapping write refused because the AP id // already maps a record in another collection. Deliberately distinct from // ErrAlreadyExists: that one is an at-uri collision (a deterministic-rkey // bug signal), this one is an id claimed as something it is not. // IsAlreadyExists(collectionImmutable) is false. ErrCollectionImmutable = errors.New("mapping collection is immutable"))
// ValidationError reports a rejected field value.type ValidationError struct { Field string Message string}
func (e ValidationError) Error() string { return fmt.Sprintf("validation error on field '%s': %s", e.Field, e.Message)}
// Unwrap makes errors.Is(err, ErrInvalidInput) true for validation errors.func (e ValidationError) Unwrap() error { return ErrInvalidInput }
// NotFoundError reports a missing resource with its identifier.type NotFoundError struct { Resource string ID any}
func (e NotFoundError) Error() string { return fmt.Sprintf("%s with ID '%v' not found", e.Resource, e.ID)}
// Unwrap makes errors.Is(err, ErrNotFound) true for not-found errors.func (e NotFoundError) Unwrap() error { return ErrNotFound }
// ConflictError reports a uniqueness conflict on a resource field.type ConflictError struct { Resource string Field string Value string}
func (e ConflictError) Error() string { return fmt.Sprintf("%s with %s '%s' already exists", e.Resource, e.Field, e.Value)}
// Unwrap makes errors.Is(err, ErrAlreadyExists) true for conflict errors.func (e ConflictError) Unwrap() error { return ErrAlreadyExists }
// TombstonedError reports a soft-deleted resource with its identifier.type TombstonedError struct { Resource string ID any}
func (e TombstonedError) Error() string { return fmt.Sprintf("%s with ID '%v' is tombstoned", e.Resource, e.ID)}
// Unwrap makes errors.Is(err, ErrTombstoned) true for tombstoned errors.func (e TombstonedError) Unwrap() error { return ErrTombstoned }
func NewValidationError(field, message string) error { return ValidationError{Field: field, Message: message}}
func NewNotFoundError(resource string, id any) error { return NotFoundError{Resource: resource, ID: id}}
func NewConflictError(resource, field, value string) error { return ConflictError{Resource: resource, Field: field, Value: value}}
func NewTombstonedError(resource string, id any) error { return TombstonedError{Resource: resource, ID: id}}
// IsNotFound reports whether err is, wraps, or unwraps to ErrNotFound.func IsNotFound(err error) bool { return errors.Is(err, ErrNotFound) }
// IsAlreadyExists reports whether err is, wraps, or unwraps to ErrAlreadyExists.func IsAlreadyExists(err error) bool { return errors.Is(err, ErrAlreadyExists) }
// IsValidation reports whether err is, wraps, or unwraps to ErrInvalidInput.func IsValidation(err error) bool { return errors.Is(err, ErrInvalidInput) }
// IsTombstoned reports whether err is, wraps, or unwraps to ErrTombstoned.func IsTombstoned(err error) bool { return errors.Is(err, ErrTombstoned) }
// IsRecordGone reports whether err is, wraps, or unwraps to ErrRecordGone.func IsRecordGone(err error) bool { return errors.Is(err, ErrRecordGone) }
// IsCollectionImmutable reports whether err is, wraps, or unwraps to// ErrCollectionImmutable.func IsCollectionImmutable(err error) bool { return errors.Is(err, ErrCollectionImmutable) }