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