-
Notifications
You must be signed in to change notification settings - Fork 492
/
errors.go
137 lines (118 loc) · 3.76 KB
/
errors.go
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
133
134
135
136
137
// Copyright 2013 Canonical Ltd.
// Licensed under the AGPLv3, see LICENCE file for details.
package common
import (
stderrors "errors"
"fmt"
"github.com/juju/errors"
"github.com/juju/names"
"github.com/juju/txn"
"github.com/juju/juju/state"
"github.com/juju/juju/state/api/params"
)
type notSupportedError struct {
tag names.Tag
operation string
}
func (e *notSupportedError) Error() string {
return fmt.Sprintf("entity %q does not support %s", e.tag, e.operation)
}
func NotSupportedError(tag names.Tag, operation string) error {
return ¬SupportedError{tag, operation}
}
type noAddressSetError struct {
unitTag names.UnitTag
addressName string
}
func (e *noAddressSetError) Error() string {
return fmt.Sprintf("%q has no %s address set", e.unitTag, e.addressName)
}
func NoAddressSetError(unitTag names.UnitTag, addressName string) error {
return &noAddressSetError{unitTag, addressName}
}
func IsNoAddressSetError(err error) bool {
_, ok := err.(*noAddressSetError)
return ok
}
type unknownEnvironmentError struct {
uuid string
}
func (e *unknownEnvironmentError) Error() string {
return fmt.Sprintf("unknown environment: %q", e.uuid)
}
func UnknownEnvironmentError(uuid string) error {
return &unknownEnvironmentError{uuid: uuid}
}
func IsUnknownEnviromentError(err error) bool {
_, ok := err.(*unknownEnvironmentError)
return ok
}
var (
ErrBadId = stderrors.New("id not found")
ErrBadCreds = stderrors.New("invalid entity name or password")
ErrPerm = stderrors.New("permission denied")
ErrNotLoggedIn = stderrors.New("not logged in")
ErrUnknownWatcher = stderrors.New("unknown watcher id")
ErrUnknownPinger = stderrors.New("unknown pinger id")
ErrStoppedWatcher = stderrors.New("watcher has been stopped")
ErrBadRequest = stderrors.New("invalid request")
ErrTryAgain = stderrors.New("try again")
)
var singletonErrorCodes = map[error]string{
state.ErrCannotEnterScopeYet: params.CodeCannotEnterScopeYet,
state.ErrCannotEnterScope: params.CodeCannotEnterScope,
state.ErrUnitHasSubordinates: params.CodeUnitHasSubordinates,
state.ErrDead: params.CodeDead,
txn.ErrExcessiveContention: params.CodeExcessiveContention,
ErrBadId: params.CodeNotFound,
ErrBadCreds: params.CodeUnauthorized,
ErrPerm: params.CodeUnauthorized,
ErrNotLoggedIn: params.CodeUnauthorized,
ErrUnknownWatcher: params.CodeNotFound,
ErrStoppedWatcher: params.CodeStopped,
ErrTryAgain: params.CodeTryAgain,
}
func singletonCode(err error) (string, bool) {
// All error types may not be hashable; deal with
// that by catching the panic if we try to look up
// a non-hashable type.
defer func() {
recover()
}()
code, ok := singletonErrorCodes[err]
return code, ok
}
// ServerError returns an error suitable for returning to an API
// client, with an error code suitable for various kinds of errors
// generated in packages outside the API.
func ServerError(err error) *params.Error {
if err == nil {
return nil
}
code, ok := singletonCode(err)
switch {
case ok:
case errors.IsUnauthorized(err):
code = params.CodeUnauthorized
case errors.IsNotFound(err):
code = params.CodeNotFound
case errors.IsAlreadyExists(err):
code = params.CodeAlreadyExists
case state.IsNotAssigned(err):
code = params.CodeNotAssigned
case state.IsHasAssignedUnitsError(err):
code = params.CodeHasAssignedUnits
case IsNoAddressSetError(err):
code = params.CodeNoAddressSet
case state.IsNotProvisionedError(err):
code = params.CodeNotProvisioned
case IsUnknownEnviromentError(err):
code = params.CodeNotFound
default:
code = params.ErrCode(err)
}
return ¶ms.Error{
Message: err.Error(),
Code: code,
}
}