1package errors
2
3import (
4 "encoding/json"
5 "fmt"
6)
7
8type XrpcError struct {
9 Tag string `json:"error"`
10 Message string `json:"message"`
11}
12
13func (x XrpcError) Error() string {
14 if x.Message != "" {
15 return fmt.Sprintf("%s: %s", x.Tag, x.Message)
16 }
17 return x.Tag
18}
19
20func NewXrpcError(opts ...ErrOpt) XrpcError {
21 x := XrpcError{}
22 for _, o := range opts {
23 o(&x)
24 }
25
26 return x
27}
28
29type ErrOpt = func(xerr *XrpcError)
30
31func WithTag(tag string) ErrOpt {
32 return func(xerr *XrpcError) {
33 xerr.Tag = tag
34 }
35}
36
37func WithMessage[S ~string](s S) ErrOpt {
38 return func(xerr *XrpcError) {
39 xerr.Message = string(s)
40 }
41}
42
43func WithError(e error) ErrOpt {
44 return func(xerr *XrpcError) {
45 xerr.Message = e.Error()
46 }
47}
48
49var MissingActorDidError = NewXrpcError(
50 WithTag("MissingActorDid"),
51 WithMessage("actor DID not supplied"),
52)
53
54var OwnerNotFoundError = NewXrpcError(
55 WithTag("OwnerNotFound"),
56 WithMessage("owner not set for this service"),
57)
58
59var AuthError = func(err error) XrpcError {
60 return NewXrpcError(
61 WithTag("Auth"),
62 WithError(fmt.Errorf("signature verification failed: %w", err)),
63 )
64}
65
66var InvalidRepoError = func(r string) XrpcError {
67 return NewXrpcError(
68 WithTag("InvalidRepo"),
69 WithError(fmt.Errorf("supplied at-uri is not a repo: %s", r)),
70 )
71}
72
73var GitError = func(e error) XrpcError {
74 return NewXrpcError(
75 WithTag("Git"),
76 WithError(fmt.Errorf("git error: %w", e)),
77 )
78}
79
80var AccessControlError = func(d string) XrpcError {
81 return NewXrpcError(
82 WithTag("AccessControl"),
83 WithError(fmt.Errorf("DID does not have sufficent access permissions for this operation: %s", d)),
84 )
85}
86
87var RepoExistsError = func(r string) XrpcError {
88 return NewXrpcError(
89 WithTag("RepoExists"),
90 WithError(fmt.Errorf("repo already exists: %s", r)),
91 )
92}
93
94var RecordExistsError = func(r string) XrpcError {
95 return NewXrpcError(
96 WithTag("RecordExists"),
97 WithError(fmt.Errorf("repo already exists: %s", r)),
98 )
99}
100
101func GenericError(err error) XrpcError {
102 return NewXrpcError(
103 WithTag("Generic"),
104 WithError(err),
105 )
106}
107
108func Unmarshal(errStr string) (XrpcError, error) {
109 var xerr XrpcError
110 err := json.Unmarshal([]byte(errStr), &xerr)
111 if err != nil {
112 return XrpcError{}, fmt.Errorf("failed to unmarshal XrpcError: %w", err)
113 }
114 return xerr, nil
115}