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