github.com/cloudbase/juju-core@v0.0.0-20140504232958-a7271ac7912f/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 "launchpad.net/juju-core/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 CodeNotImplemented = rpc.CodeNotImplemented 48 ) 49 50 // ErrCode returns the error code associated with 51 // the given error, or the empty string if there 52 // is none. 53 func ErrCode(err error) string { 54 if err, _ := err.(rpc.ErrorCoder); err != nil { 55 return err.ErrorCode() 56 } 57 return "" 58 } 59 60 // clientError maps errors returned from an RPC call into local errors with 61 // appropriate values. 62 func ClientError(err error) error { 63 rerr, ok := err.(*rpc.RequestError) 64 if !ok { 65 return err 66 } 67 // We use our own error type rather than rpc.ServerError 68 // because we don't want the code or the "server error" prefix 69 // within the error message. Also, it's best not to make clients 70 // know that we're using the rpc package. 71 return &Error{ 72 Message: rerr.Message, 73 Code: rerr.Code, 74 } 75 } 76 77 func IsCodeNotFound(err error) bool { 78 return ErrCode(err) == CodeNotFound 79 } 80 81 func IsCodeUnauthorized(err error) bool { 82 return ErrCode(err) == CodeUnauthorized 83 } 84 85 // IsCodeNotFoundOrCodeUnauthorized is used in API clients which, pre-API, used 86 // IsNotFoundErr; this is because an API client is not necessarily privileged to 87 // know about the existence or otherwise of a particular entity, and the server 88 // may hence convert NotFound to Unauthorized at its discretion. 89 func IsCodeNotFoundOrCodeUnauthorized(err error) bool { 90 return IsCodeNotFound(err) || IsCodeUnauthorized(err) 91 } 92 93 func IsCodeCannotEnterScope(err error) bool { 94 return ErrCode(err) == CodeCannotEnterScope 95 } 96 97 func IsCodeCannotEnterScopeYet(err error) bool { 98 return ErrCode(err) == CodeCannotEnterScopeYet 99 } 100 101 func IsCodeExcessiveContention(err error) bool { 102 return ErrCode(err) == CodeExcessiveContention 103 } 104 105 func IsCodeUnitHasSubordinates(err error) bool { 106 return ErrCode(err) == CodeUnitHasSubordinates 107 } 108 109 func IsCodeNotAssigned(err error) bool { 110 return ErrCode(err) == CodeNotAssigned 111 } 112 113 func IsCodeStopped(err error) bool { 114 return ErrCode(err) == CodeStopped 115 } 116 117 func IsCodeHasAssignedUnits(err error) bool { 118 return ErrCode(err) == CodeHasAssignedUnits 119 } 120 121 func IsCodeNotProvisioned(err error) bool { 122 return ErrCode(err) == CodeNotProvisioned 123 } 124 125 func IsCodeNoAddressSet(err error) bool { 126 return ErrCode(err) == CodeNoAddressSet 127 } 128 129 func IsCodeNotImplemented(err error) bool { 130 return ErrCode(err) == CodeNotImplemented 131 }