package errors
import (
"encoding/json"
"fmt"
)
type XrpcError struct {
Tag string `json:"error"`
Message string `json:"message"`
}
func (x XrpcError) Error() string {
if x.Message != "" {
return fmt.Sprintf("%s: %s", x.Tag, x.Message)
}
return x.Tag
}
func NewXrpcError(opts ...ErrOpt) XrpcError {
x := XrpcError{}
for _, o := range opts {
o(&x)
}
return x
}
type ErrOpt = func(xerr *XrpcError)
func WithTag(tag string) ErrOpt {
return func(xerr *XrpcError) {
xerr.Tag = tag
}
}
func WithMessage[S ~string](s S) ErrOpt {
return func(xerr *XrpcError) {
xerr.Message = string(s)
}
}
func WithError(e error) ErrOpt {
return func(xerr *XrpcError) {
xerr.Message = e.Error()
}
}
var MissingActorDidError = NewXrpcError(
WithTag("MissingActorDid"),
WithMessage("actor DID not supplied"),
)
var OwnerNotFoundError = NewXrpcError(
WithTag("OwnerNotFound"),
WithMessage("owner not set for this service"),
)
var RepoNotFoundError = NewXrpcError(
WithTag("RepoNotFound"),
WithMessage("failed to access repository"),
)
var WebhookLimitExceededError = NewXrpcError(
WithTag("WebhookLimitExceeded"),
WithMessage("this repository or account has reached its webhook limit"),
)
var RefNotFoundError = NewXrpcError(
WithTag("RefNotFound"),
WithMessage("failed to access ref"),
)
var RequestTooLargeError = NewXrpcError(
WithTag("RequestTooLarge"),
WithMessage("request was too large"),
)
var AuthError = func(err error) XrpcError {
return NewXrpcError(
WithTag("Auth"),
WithError(fmt.Errorf("signature verification failed: %w", err)),
)
}
var InvalidRepoError = func(r string) XrpcError {
return NewXrpcError(
WithTag("InvalidRepo"),
WithError(fmt.Errorf("supplied repo identifier is invalid: %s", r)),
)
}
var GitError = func(e error) XrpcError {
return NewXrpcError(
WithTag("Git"),
WithError(fmt.Errorf("git error: %w", e)),
)
}
var AccessControlError = func(d string) XrpcError {
return NewXrpcError(
WithTag("AccessControl"),
WithError(fmt.Errorf("DID does not have sufficient access permissions for this operation: %s", d)),
)
}
var RepoExistsError = func(r string) XrpcError {
return NewXrpcError(
WithTag("RepoExists"),
WithError(fmt.Errorf("repo already exists: %s", r)),
)
}
var RecordExistsError = func(r string) XrpcError {
return NewXrpcError(
WithTag("RecordExists"),
WithError(fmt.Errorf("repo already exists: %s", r)),
)
}
func GenericError(err error) XrpcError {
return NewXrpcError(
WithTag("Generic"),
WithError(err),
)
}
func Unmarshal(errStr string) (XrpcError, error) {
var xerr XrpcError
err := json.Unmarshal([]byte(errStr), &xerr)
if err != nil {
return XrpcError{}, fmt.Errorf("failed to unmarshal XrpcError: %w", err)
}
return xerr, nil
}