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("&params.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  }