github.com/cloudbase/juju-core@v0.0.0-20140504232958-a7271ac7912f/state/apiserver/common/errors.go (about) 1 // Copyright 2013 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package common 5 6 import ( 7 stderrors "errors" 8 "fmt" 9 10 "launchpad.net/juju-core/errors" 11 "launchpad.net/juju-core/state" 12 "launchpad.net/juju-core/state/api/params" 13 ) 14 15 type notSupportedError struct { 16 entity string 17 operation string 18 } 19 20 func (e *notSupportedError) Error() string { 21 return fmt.Sprintf("entity %q does not support %s", e.entity, e.operation) 22 } 23 24 func NotSupportedError(entity, operation string) error { 25 return ¬SupportedError{entity, operation} 26 } 27 28 type noAddressSetError struct { 29 unitTag string 30 addressName string 31 } 32 33 func (e *noAddressSetError) Error() string { 34 return fmt.Sprintf("%q has no %s address set", e.unitTag, e.addressName) 35 } 36 37 func NoAddressSetError(unitTag, addressName string) error { 38 return &noAddressSetError{unitTag, addressName} 39 } 40 41 func IsNoAddressSetError(err error) bool { 42 _, ok := err.(*noAddressSetError) 43 return ok 44 } 45 46 var ( 47 ErrBadId = stderrors.New("id not found") 48 ErrBadCreds = stderrors.New("invalid entity name or password") 49 ErrPerm = stderrors.New("permission denied") 50 ErrNotLoggedIn = stderrors.New("not logged in") 51 ErrUnknownWatcher = stderrors.New("unknown watcher id") 52 ErrUnknownPinger = stderrors.New("unknown pinger id") 53 ErrStoppedWatcher = stderrors.New("watcher has been stopped") 54 ErrBadRequest = stderrors.New("invalid request") 55 ) 56 57 var singletonErrorCodes = map[error]string{ 58 state.ErrCannotEnterScopeYet: params.CodeCannotEnterScopeYet, 59 state.ErrCannotEnterScope: params.CodeCannotEnterScope, 60 state.ErrExcessiveContention: params.CodeExcessiveContention, 61 state.ErrUnitHasSubordinates: params.CodeUnitHasSubordinates, 62 ErrBadId: params.CodeNotFound, 63 ErrBadCreds: params.CodeUnauthorized, 64 ErrPerm: params.CodeUnauthorized, 65 ErrNotLoggedIn: params.CodeUnauthorized, 66 ErrUnknownWatcher: params.CodeNotFound, 67 ErrStoppedWatcher: params.CodeStopped, 68 } 69 70 func singletonCode(err error) (string, bool) { 71 // All error types may not be hashable; deal with 72 // that by catching the panic if we try to look up 73 // a non-hashable type. 74 defer func() { 75 recover() 76 }() 77 code, ok := singletonErrorCodes[err] 78 return code, ok 79 } 80 81 // ServerError returns an error suitable for returning to an API 82 // client, with an error code suitable for various kinds of errors 83 // generated in packages outside the API. 84 func ServerError(err error) *params.Error { 85 if err == nil { 86 return nil 87 } 88 code, ok := singletonCode(err) 89 switch { 90 case ok: 91 case errors.IsUnauthorizedError(err): 92 code = params.CodeUnauthorized 93 case errors.IsNotFoundError(err): 94 code = params.CodeNotFound 95 case state.IsNotAssigned(err): 96 code = params.CodeNotAssigned 97 case state.IsHasAssignedUnitsError(err): 98 code = params.CodeHasAssignedUnits 99 case IsNoAddressSetError(err): 100 code = params.CodeNoAddressSet 101 case state.IsNotProvisionedError(err): 102 code = params.CodeNotProvisioned 103 default: 104 code = params.ErrCode(err) 105 } 106 return ¶ms.Error{ 107 Message: err.Error(), 108 Code: code, 109 } 110 }