...

Source file src/github.com/docker/distribution/registry/api/errcode/register.go

Documentation: github.com/docker/distribution/registry/api/errcode

     1  package errcode
     2  
     3  import (
     4  	"fmt"
     5  	"net/http"
     6  	"sort"
     7  	"sync"
     8  )
     9  
    10  var (
    11  	errorCodeToDescriptors = map[ErrorCode]ErrorDescriptor{}
    12  	idToDescriptors        = map[string]ErrorDescriptor{}
    13  	groupToDescriptors     = map[string][]ErrorDescriptor{}
    14  )
    15  
    16  var (
    17  	// ErrorCodeUnknown is a generic error that can be used as a last
    18  	// resort if there is no situation-specific error message that can be used
    19  	ErrorCodeUnknown = Register("errcode", ErrorDescriptor{
    20  		Value:   "UNKNOWN",
    21  		Message: "unknown error",
    22  		Description: `Generic error returned when the error does not have an
    23  			                                            API classification.`,
    24  		HTTPStatusCode: http.StatusInternalServerError,
    25  	})
    26  
    27  	// ErrorCodeUnsupported is returned when an operation is not supported.
    28  	ErrorCodeUnsupported = Register("errcode", ErrorDescriptor{
    29  		Value:   "UNSUPPORTED",
    30  		Message: "The operation is unsupported.",
    31  		Description: `The operation was unsupported due to a missing
    32  		implementation or invalid set of parameters.`,
    33  		HTTPStatusCode: http.StatusMethodNotAllowed,
    34  	})
    35  
    36  	// ErrorCodeUnauthorized is returned if a request requires
    37  	// authentication.
    38  	ErrorCodeUnauthorized = Register("errcode", ErrorDescriptor{
    39  		Value:   "UNAUTHORIZED",
    40  		Message: "authentication required",
    41  		Description: `The access controller was unable to authenticate
    42  		the client. Often this will be accompanied by a
    43  		Www-Authenticate HTTP response header indicating how to
    44  		authenticate.`,
    45  		HTTPStatusCode: http.StatusUnauthorized,
    46  	})
    47  
    48  	// ErrorCodeDenied is returned if a client does not have sufficient
    49  	// permission to perform an action.
    50  	ErrorCodeDenied = Register("errcode", ErrorDescriptor{
    51  		Value:   "DENIED",
    52  		Message: "requested access to the resource is denied",
    53  		Description: `The access controller denied access for the
    54  		operation on a resource.`,
    55  		HTTPStatusCode: http.StatusForbidden,
    56  	})
    57  
    58  	// ErrorCodeUnavailable provides a common error to report unavailability
    59  	// of a service or endpoint.
    60  	ErrorCodeUnavailable = Register("errcode", ErrorDescriptor{
    61  		Value:          "UNAVAILABLE",
    62  		Message:        "service unavailable",
    63  		Description:    "Returned when a service is not available",
    64  		HTTPStatusCode: http.StatusServiceUnavailable,
    65  	})
    66  
    67  	// ErrorCodeTooManyRequests is returned if a client attempts too many
    68  	// times to contact a service endpoint.
    69  	ErrorCodeTooManyRequests = Register("errcode", ErrorDescriptor{
    70  		Value:   "TOOMANYREQUESTS",
    71  		Message: "too many requests",
    72  		Description: `Returned when a client attempts to contact a
    73  		service too many times`,
    74  		HTTPStatusCode: http.StatusTooManyRequests,
    75  	})
    76  )
    77  
    78  var nextCode = 1000
    79  var registerLock sync.Mutex
    80  
    81  // Register will make the passed-in error known to the environment and
    82  // return a new ErrorCode
    83  func Register(group string, descriptor ErrorDescriptor) ErrorCode {
    84  	registerLock.Lock()
    85  	defer registerLock.Unlock()
    86  
    87  	descriptor.Code = ErrorCode(nextCode)
    88  
    89  	if _, ok := idToDescriptors[descriptor.Value]; ok {
    90  		panic(fmt.Sprintf("ErrorValue %q is already registered", descriptor.Value))
    91  	}
    92  	if _, ok := errorCodeToDescriptors[descriptor.Code]; ok {
    93  		panic(fmt.Sprintf("ErrorCode %v is already registered", descriptor.Code))
    94  	}
    95  
    96  	groupToDescriptors[group] = append(groupToDescriptors[group], descriptor)
    97  	errorCodeToDescriptors[descriptor.Code] = descriptor
    98  	idToDescriptors[descriptor.Value] = descriptor
    99  
   100  	nextCode++
   101  	return descriptor.Code
   102  }
   103  
   104  type byValue []ErrorDescriptor
   105  
   106  func (a byValue) Len() int           { return len(a) }
   107  func (a byValue) Swap(i, j int)      { a[i], a[j] = a[j], a[i] }
   108  func (a byValue) Less(i, j int) bool { return a[i].Value < a[j].Value }
   109  
   110  // GetGroupNames returns the list of Error group names that are registered
   111  func GetGroupNames() []string {
   112  	keys := []string{}
   113  
   114  	for k := range groupToDescriptors {
   115  		keys = append(keys, k)
   116  	}
   117  	sort.Strings(keys)
   118  	return keys
   119  }
   120  
   121  // GetErrorCodeGroup returns the named group of error descriptors
   122  func GetErrorCodeGroup(name string) []ErrorDescriptor {
   123  	desc := groupToDescriptors[name]
   124  	sort.Sort(byValue(desc))
   125  	return desc
   126  }
   127  
   128  // GetErrorAllDescriptors returns a slice of all ErrorDescriptors that are
   129  // registered, irrespective of what group they're in
   130  func GetErrorAllDescriptors() []ErrorDescriptor {
   131  	result := []ErrorDescriptor{}
   132  
   133  	for _, group := range GetGroupNames() {
   134  		result = append(result, GetErrorCodeGroup(group)...)
   135  	}
   136  	sort.Sort(byValue(result))
   137  	return result
   138  }
   139  

View as plain text