sentinels.go

v0.3.0
Doc Versions Source
1
package httpproblem
2
3
// Typed sentinel errors. Each implements the error interface so callers
4
// can return them directly, and each round-trips through errors.As so
5
// callers can branch on a specific category without depending on this
6
// package's mapping table.
7
8
// NotFoundError indicates the requested resource does not exist.
9
type NotFoundError struct{ Resource string }
10
11
// Error implements error.
12
func (e NotFoundError) Error() string {
13
	if e.Resource == "" {
14
		return "not found"
15
	}
16
	return "not found: " + e.Resource
17
}
18
19
// detail returns the human-readable detail line for the matching Problem.
20
// Kept private so callers cannot accidentally rely on the formatting.
21
func (e NotFoundError) detail() string {
22
	if e.Resource == "" {
23
		return ""
24
	}
25
	return e.Resource + " not found"
26
}
27
28
// BadRequestError indicates malformed or invalid input from the caller.
29
type BadRequestError struct{ Detail string }
30
31
// Error implements error.
32
func (e BadRequestError) Error() string {
33
	if e.Detail == "" {
34
		return "bad request"
35
	}
36
	return "bad request: " + e.Detail
37
}
38
39
// ConflictError indicates the request conflicts with current resource state.
40
type ConflictError struct{ Detail string }
41
42
// Error implements error.
43
func (e ConflictError) Error() string {
44
	if e.Detail == "" {
45
		return "conflict"
46
	}
47
	return "conflict: " + e.Detail
48
}
49
50
// UnauthorizedError indicates the request lacks valid authentication.
51
type UnauthorizedError struct{ Detail string }
52
53
// Error implements error.
54
func (e UnauthorizedError) Error() string {
55
	if e.Detail == "" {
56
		return "unauthorized"
57
	}
58
	return "unauthorized: " + e.Detail
59
}
60
61
// ForbiddenError indicates the request is authenticated but not allowed.
62
type ForbiddenError struct{ Detail string }
63
64
// Error implements error.
65
func (e ForbiddenError) Error() string {
66
	if e.Detail == "" {
67
		return "forbidden"
68
	}
69
	return "forbidden: " + e.Detail
70
}
71
72
// UnprocessableError indicates a syntactically valid request that cannot
73
// be processed (RFC 4918 ยง11.2).
74
type UnprocessableError struct{ Detail string }
75
76
// Error implements error.
77
func (e UnprocessableError) Error() string {
78
	if e.Detail == "" {
79
		return "unprocessable entity"
80
	}
81
	return "unprocessable entity: " + e.Detail
82
}
83
84
// TooManyRequestsError indicates the caller has hit a rate limit.
85
type TooManyRequestsError struct{ Detail string }
86
87
// Error implements error.
88
func (e TooManyRequestsError) Error() string {
89
	if e.Detail == "" {
90
		return "too many requests"
91
	}
92
	return "too many requests: " + e.Detail
93
}
94
95
// InternalError indicates an unrecoverable server-side failure. The Detail
96
// field is for internal logging only โ€” it never appears in the HTTP
97
// response body unless an explicit culpa.PublicDetail is attached.
98
type InternalError struct{ Detail string }
99
100
// Error implements error.
101
func (e InternalError) Error() string {
102
	if e.Detail == "" {
103
		return "internal server error"
104
	}
105
	return "internal server error: " + e.Detail
106
}
107
108
// NotFound returns a [NotFoundError] for the given resource name.
109
func NotFound(resource string) error { return NotFoundError{Resource: resource} }
110
111
// BadRequest returns a [BadRequestError] with the given detail message.
112
func BadRequest(detail string) error { return BadRequestError{Detail: detail} }
113
114
// Conflict returns a [ConflictError] with the given detail message.
115
func Conflict(detail string) error { return ConflictError{Detail: detail} }
116
117
// Unauthorized returns an [UnauthorizedError] with the given detail message.
118
func Unauthorized(detail string) error { return UnauthorizedError{Detail: detail} }
119
120
// Forbidden returns a [ForbiddenError] with the given detail message.
121
func Forbidden(detail string) error { return ForbiddenError{Detail: detail} }
122
123
// Unprocessable returns an [UnprocessableError] with the given detail message.
124
func Unprocessable(detail string) error { return UnprocessableError{Detail: detail} }
125
126
// TooManyRequests returns a [TooManyRequestsError] with the given detail message.
127
func TooManyRequests(detail string) error { return TooManyRequestsError{Detail: detail} }
128
129
// Internal returns an [InternalError] with the given detail message. The
130
// detail is for logs only; it does not appear in the HTTP response body.
131
func Internal(detail string) error { return InternalError{Detail: detail} }
132

Source Files