summaryrefslogtreecommitdiff
path: root/internal/federation/dereferencing/error.go
blob: 4e5d1cd225a1cc9a2905e03a6003f577800736c9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
/*
   GoToSocial
   Copyright (C) 2021-2022 GoToSocial Authors admin@gotosocial.org

   This program is free software: you can redistribute it and/or modify
   it under the terms of the GNU Affero General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU Affero General Public License for more details.

   You should have received a copy of the GNU Affero General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

package dereferencing

import (
	"errors"
	"fmt"

	"github.com/superseriousbusiness/gotosocial/internal/transport"
)

// ErrDB denotes that a proper error has occurred when doing
// a database call, as opposed to a simple db.ErrNoEntries.
type ErrDB struct {
	wrapped error
}

func (err *ErrDB) Error() string {
	return fmt.Sprintf("database error during dereferencing: %v", err.wrapped)
}

func newErrDB(err error) error {
	return &ErrDB{wrapped: err}
}

// ErrNotRetrievable denotes that an item could not be dereferenced
// with the given parameters.
type ErrNotRetrievable struct {
	wrapped error
}

func (err *ErrNotRetrievable) Error() string {
	return fmt.Sprintf("item could not be retrieved: %v", err.wrapped)
}

func newErrNotRetrievable(err error) error {
	return &ErrNotRetrievable{wrapped: err}
}

// ErrBadRequest denotes that insufficient or improperly formed parameters
// were passed into one of the dereference functions.
type ErrBadRequest struct {
	wrapped error
}

func (err *ErrBadRequest) Error() string {
	return fmt.Sprintf("bad request: %v", err.wrapped)
}

func newErrBadRequest(err error) error {
	return &ErrBadRequest{wrapped: err}
}

// ErrTransportError indicates that something unforeseen went wrong creating
// a transport, or while making an http call to a remote resource with a transport.
type ErrTransportError struct {
	wrapped error
}

func (err *ErrTransportError) Error() string {
	return fmt.Sprintf("transport error: %v", err.wrapped)
}

func newErrTransportError(err error) error {
	return &ErrTransportError{wrapped: err}
}

// ErrWrongType indicates that an unexpected type was returned from a remote call;
// for example, we were served a Person when we were looking for a statusable.
type ErrWrongType struct {
	wrapped error
}

func (err *ErrWrongType) Error() string {
	return fmt.Sprintf("wrong received type: %v", err.wrapped)
}

func newErrWrongType(err error) error {
	return &ErrWrongType{wrapped: err}
}

// ErrOther denotes some other kind of weird error, perhaps from a malformed json
// or some other weird crapola.
type ErrOther struct {
	wrapped error
}

func (err *ErrOther) Error() string {
	return fmt.Sprintf("unexpected error: %v", err.wrapped)
}

func newErrOther(err error) error {
	return &ErrOther{wrapped: err}
}

func wrapDerefError(derefErr error, fluff string) error {
	var (
		err          error
		errWrongType *ErrWrongType
	)

	if fluff != "" {
		err = fmt.Errorf("%s: %w", fluff, derefErr)
	}

	switch {
	case errors.Is(derefErr, transport.ErrGone):
		err = newErrNotRetrievable(err)
	case errors.As(derefErr, &errWrongType):
		err = newErrWrongType(err)
	default:
		err = newErrTransportError(err)
	}

	return err
}