github.com/makyo/juju@v0.0.0-20160425123129-2608902037e9/apiserver/params/apierror.go (about) 1 // Copyright 2013 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package params 5 6 import ( 7 "fmt" 8 9 "github.com/juju/errors" 10 "gopkg.in/macaroon.v1" 11 ) 12 13 // UpgradeInProgressError signifies an upgrade is in progress. 14 var UpgradeInProgressError = errors.New(CodeUpgradeInProgress) 15 16 // Error is the type of error returned by any call to the state API. 17 type Error struct { 18 Message string 19 Code string 20 Info *ErrorInfo `json:",omitempty"` 21 } 22 23 // ErrorInfo holds additional information provided by an error. 24 // Note that although these fields are compatible with the 25 // same fields in httpbakery.ErrorInfo, the Juju API server does 26 // not implement endpoints directly compatible with that protocol 27 // because the error response format varies according to 28 // the endpoint. 29 type ErrorInfo struct { 30 // Macaroon may hold a macaroon that, when 31 // discharged, may allow access to the juju API. 32 // This field is associated with the ErrDischargeRequired 33 // error code. 34 Macaroon *macaroon.Macaroon `json:",omitempty"` 35 36 // MacaroonPath holds the URL path to be associated 37 // with the macaroon. The macaroon is potentially 38 // valid for all URLs under the given path. 39 // If it is empty, the macaroon will be associated with 40 // the original URL from which the error was returned. 41 MacaroonPath string `json:",omitempty"` 42 } 43 44 func (e Error) Error() string { 45 return e.Message 46 } 47 48 func (e Error) ErrorCode() string { 49 return e.Code 50 } 51 52 // GoString implements fmt.GoStringer. It means that a *Error shows its 53 // contents correctly when printed with %#v. 54 func (e Error) GoString() string { 55 return fmt.Sprintf("¶ms.Error{Message: %q, Code: %q}", e.Message, e.Code) 56 } 57 58 // The Code constants hold error codes for some kinds of error. 59 const ( 60 CodeNotFound = "not found" 61 CodeUnauthorized = "unauthorized access" 62 CodeCannotEnterScope = "cannot enter scope" 63 CodeCannotEnterScopeYet = "cannot enter scope yet" 64 CodeExcessiveContention = "excessive contention" 65 CodeUnitHasSubordinates = "unit has subordinates" 66 CodeNotAssigned = "not assigned" 67 CodeStopped = "stopped" 68 CodeDead = "dead" 69 CodeHasAssignedUnits = "machine has assigned units" 70 CodeHasHostedModels = "controller has hosted models" 71 CodeMachineHasAttachedStorage = "machine has attached storage" 72 CodeNotProvisioned = "not provisioned" 73 CodeNoAddressSet = "no address set" 74 CodeTryAgain = "try again" 75 CodeNotImplemented = "not implemented" // asserted to match rpc.codeNotImplemented in rpc/rpc_test.go 76 CodeAlreadyExists = "already exists" 77 CodeUpgradeInProgress = "upgrade in progress" 78 CodeActionNotAvailable = "action no longer available" 79 CodeOperationBlocked = "operation is blocked" 80 CodeLeadershipClaimDenied = "leadership claim denied" 81 CodeLeaseClaimDenied = "lease claim denied" 82 CodeNotSupported = "not supported" 83 CodeBadRequest = "bad request" 84 CodeMethodNotAllowed = "method not allowed" 85 CodeForbidden = "forbidden" 86 CodeDischargeRequired = "macaroon discharge required" 87 ) 88 89 // ErrCode returns the error code associated with 90 // the given error, or the empty string if there 91 // is none. 92 func ErrCode(err error) string { 93 type ErrorCoder interface { 94 ErrorCode() string 95 } 96 switch err := errors.Cause(err).(type) { 97 case ErrorCoder: 98 return err.ErrorCode() 99 default: 100 return "" 101 } 102 } 103 104 func IsCodeActionNotAvailable(err error) bool { 105 return ErrCode(err) == CodeActionNotAvailable 106 } 107 108 func IsCodeNotFound(err error) bool { 109 return ErrCode(err) == CodeNotFound 110 } 111 112 func IsCodeUnauthorized(err error) bool { 113 return ErrCode(err) == CodeUnauthorized 114 } 115 116 // IsCodeNotFoundOrCodeUnauthorized is used in API clients which, 117 // pre-API, used errors.IsNotFound; this is because an API client is 118 // not necessarily privileged to know about the existence or otherwise 119 // of a particular entity, and the server may hence convert NotFound 120 // to Unauthorized at its discretion. 121 func IsCodeNotFoundOrCodeUnauthorized(err error) bool { 122 return IsCodeNotFound(err) || IsCodeUnauthorized(err) 123 } 124 125 func IsCodeCannotEnterScope(err error) bool { 126 return ErrCode(err) == CodeCannotEnterScope 127 } 128 129 func IsCodeCannotEnterScopeYet(err error) bool { 130 return ErrCode(err) == CodeCannotEnterScopeYet 131 } 132 133 func IsCodeExcessiveContention(err error) bool { 134 return ErrCode(err) == CodeExcessiveContention 135 } 136 137 func IsCodeUnitHasSubordinates(err error) bool { 138 return ErrCode(err) == CodeUnitHasSubordinates 139 } 140 141 func IsCodeNotAssigned(err error) bool { 142 return ErrCode(err) == CodeNotAssigned 143 } 144 145 func IsCodeStopped(err error) bool { 146 return ErrCode(err) == CodeStopped 147 } 148 149 func IsCodeDead(err error) bool { 150 return ErrCode(err) == CodeDead 151 } 152 153 func IsCodeHasAssignedUnits(err error) bool { 154 return ErrCode(err) == CodeHasAssignedUnits 155 } 156 157 func IsCodeHasHostedModels(err error) bool { 158 return ErrCode(err) == CodeHasHostedModels 159 } 160 161 func IsCodeMachineHasAttachedStorage(err error) bool { 162 return ErrCode(err) == CodeMachineHasAttachedStorage 163 } 164 165 func IsCodeNotProvisioned(err error) bool { 166 return ErrCode(err) == CodeNotProvisioned 167 } 168 169 func IsCodeNoAddressSet(err error) bool { 170 return ErrCode(err) == CodeNoAddressSet 171 } 172 173 func IsCodeTryAgain(err error) bool { 174 return ErrCode(err) == CodeTryAgain 175 } 176 177 func IsCodeNotImplemented(err error) bool { 178 return ErrCode(err) == CodeNotImplemented 179 } 180 181 func IsCodeAlreadyExists(err error) bool { 182 return ErrCode(err) == CodeAlreadyExists 183 } 184 185 func IsCodeUpgradeInProgress(err error) bool { 186 return ErrCode(err) == CodeUpgradeInProgress 187 } 188 189 func IsCodeOperationBlocked(err error) bool { 190 return ErrCode(err) == CodeOperationBlocked 191 } 192 193 func IsCodeLeadershipClaimDenied(err error) bool { 194 return ErrCode(err) == CodeLeadershipClaimDenied 195 } 196 197 func IsCodeLeaseClaimDenied(err error) bool { 198 return ErrCode(err) == CodeLeaseClaimDenied 199 } 200 201 func IsCodeNotSupported(err error) bool { 202 return ErrCode(err) == CodeNotSupported 203 } 204 205 func IsBadRequest(err error) bool { 206 return ErrCode(err) == CodeBadRequest 207 } 208 209 func IsMethodNotAllowed(err error) bool { 210 return ErrCode(err) == CodeMethodNotAllowed 211 }