github.com/cloud-green/juju@v0.0.0-20151002100041-a00291338d3d/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 11 "github.com/juju/juju/rpc" 12 ) 13 14 // Error is the type of error returned by any call to the state API 15 type Error struct { 16 Message string 17 Code string 18 } 19 20 func (e *Error) Error() string { 21 return e.Message 22 } 23 24 func (e *Error) ErrorCode() string { 25 return e.Code 26 } 27 28 var _ rpc.ErrorCoder = (*Error)(nil) 29 30 // GoString implements fmt.GoStringer. It means that a *Error shows its 31 // contents correctly when printed with %#v. 32 func (e Error) GoString() string { 33 return fmt.Sprintf("¶ms.Error{%q, %q}", e.Code, e.Message) 34 } 35 36 // The Code constants hold error codes for some kinds of error. 37 const ( 38 CodeNotFound = "not found" 39 CodeUnauthorized = "unauthorized access" 40 CodeCannotEnterScope = "cannot enter scope" 41 CodeCannotEnterScopeYet = "cannot enter scope yet" 42 CodeExcessiveContention = "excessive contention" 43 CodeUnitHasSubordinates = "unit has subordinates" 44 CodeNotAssigned = "not assigned" 45 CodeStopped = "stopped" 46 CodeDead = "dead" 47 CodeHasAssignedUnits = "machine has assigned units" 48 CodeMachineHasAttachedStorage = "machine has attached storage" 49 CodeNotProvisioned = "not provisioned" 50 CodeNoAddressSet = "no address set" 51 CodeTryAgain = "try again" 52 CodeNotImplemented = rpc.CodeNotImplemented 53 CodeAlreadyExists = "already exists" 54 CodeUpgradeInProgress = "upgrade in progress" 55 CodeActionNotAvailable = "action no longer available" 56 CodeOperationBlocked = "operation is blocked" 57 CodeLeadershipClaimDenied = "leadership claim denied" 58 CodeNotSupported = "not supported" 59 ) 60 61 // ErrCode returns the error code associated with 62 // the given error, or the empty string if there 63 // is none. 64 func ErrCode(err error) string { 65 err = errors.Cause(err) 66 if err, _ := err.(rpc.ErrorCoder); err != nil { 67 return err.ErrorCode() 68 } 69 return "" 70 } 71 72 // ClientError maps errors returned from an RPC call into local errors with 73 // appropriate values. 74 func ClientError(err error) error { 75 rerr, ok := err.(*rpc.RequestError) 76 if !ok { 77 return err 78 } 79 // We use our own error type rather than rpc.ServerError 80 // because we don't want the code or the "server error" prefix 81 // within the error message. Also, it's best not to make clients 82 // know that we're using the rpc package. 83 return &Error{ 84 Message: rerr.Message, 85 Code: rerr.Code, 86 } 87 } 88 89 func IsCodeActionNotAvailable(err error) bool { 90 return ErrCode(err) == CodeActionNotAvailable 91 } 92 93 func IsCodeNotFound(err error) bool { 94 return ErrCode(err) == CodeNotFound 95 } 96 97 func IsCodeUnauthorized(err error) bool { 98 return ErrCode(err) == CodeUnauthorized 99 } 100 101 // IsCodeNotFoundOrCodeUnauthorized is used in API clients which, 102 // pre-API, used errors.IsNotFound; this is because an API client is 103 // not necessarily privileged to know about the existence or otherwise 104 // of a particular entity, and the server may hence convert NotFound 105 // to Unauthorized at its discretion. 106 func IsCodeNotFoundOrCodeUnauthorized(err error) bool { 107 return IsCodeNotFound(err) || IsCodeUnauthorized(err) 108 } 109 110 func IsCodeCannotEnterScope(err error) bool { 111 return ErrCode(err) == CodeCannotEnterScope 112 } 113 114 func IsCodeCannotEnterScopeYet(err error) bool { 115 return ErrCode(err) == CodeCannotEnterScopeYet 116 } 117 118 func IsCodeExcessiveContention(err error) bool { 119 return ErrCode(err) == CodeExcessiveContention 120 } 121 122 func IsCodeUnitHasSubordinates(err error) bool { 123 return ErrCode(err) == CodeUnitHasSubordinates 124 } 125 126 func IsCodeNotAssigned(err error) bool { 127 return ErrCode(err) == CodeNotAssigned 128 } 129 130 func IsCodeStopped(err error) bool { 131 return ErrCode(err) == CodeStopped 132 } 133 134 func IsCodeDead(err error) bool { 135 return ErrCode(err) == CodeDead 136 } 137 138 func IsCodeHasAssignedUnits(err error) bool { 139 return ErrCode(err) == CodeHasAssignedUnits 140 } 141 142 func IsCodeMachineHasAttachedStorage(err error) bool { 143 return ErrCode(err) == CodeMachineHasAttachedStorage 144 } 145 146 func IsCodeNotProvisioned(err error) bool { 147 return ErrCode(err) == CodeNotProvisioned 148 } 149 150 func IsCodeNoAddressSet(err error) bool { 151 return ErrCode(err) == CodeNoAddressSet 152 } 153 154 func IsCodeTryAgain(err error) bool { 155 return ErrCode(err) == CodeTryAgain 156 } 157 158 func IsCodeNotImplemented(err error) bool { 159 return ErrCode(err) == CodeNotImplemented 160 } 161 162 func IsCodeAlreadyExists(err error) bool { 163 return ErrCode(err) == CodeAlreadyExists 164 } 165 166 func IsCodeUpgradeInProgress(err error) bool { 167 return ErrCode(err) == CodeUpgradeInProgress 168 } 169 170 func IsCodeOperationBlocked(err error) bool { 171 return ErrCode(err) == CodeOperationBlocked 172 } 173 174 func IsCodeLeadershipClaimDenied(err error) bool { 175 return ErrCode(err) == CodeLeadershipClaimDenied 176 } 177 178 func IsCodeNotSupported(err error) bool { 179 return ErrCode(err) == CodeNotSupported 180 }