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