zotregistry.io/zot@v1.4.4-0.20231124084042-02a8ed785457/pkg/api/errors/errors.go (about)

     1  package errors
     2  
     3  import (
     4  	"zotregistry.io/zot/errors"
     5  )
     6  
     7  type Error struct {
     8  	Code        string            `json:"code"`
     9  	Message     string            `json:"message"`
    10  	Description string            `json:"-"`
    11  	Detail      map[string]string `json:"detail"`
    12  }
    13  
    14  type ErrorList struct {
    15  	Errors []*Error `json:"errors"`
    16  }
    17  
    18  type ErrorCode int
    19  
    20  //nolint:golint,stylecheck,revive
    21  const (
    22  	BLOB_UNKNOWN ErrorCode = iota
    23  	BLOB_UPLOAD_INVALID
    24  	BLOB_UPLOAD_UNKNOWN
    25  	DIGEST_INVALID
    26  	MANIFEST_BLOB_UNKNOWN
    27  	MANIFEST_INVALID
    28  	MANIFEST_UNKNOWN
    29  	NAME_INVALID
    30  	NAME_UNKNOWN
    31  	SIZE_INVALID
    32  	UNAUTHORIZED
    33  	DENIED
    34  	UNSUPPORTED
    35  	TOOMANYREQUESTS
    36  )
    37  
    38  func (e ErrorCode) String() string {
    39  	errMap := map[ErrorCode]string{
    40  		BLOB_UNKNOWN:          "BLOB_UNKNOWN",
    41  		BLOB_UPLOAD_INVALID:   "BLOB_UPLOAD_INVALID",
    42  		BLOB_UPLOAD_UNKNOWN:   "BLOB_UPLOAD_UNKNOWN",
    43  		DIGEST_INVALID:        "DIGEST_INVALID",
    44  		MANIFEST_BLOB_UNKNOWN: "MANIFEST_BLOB_UNKNOWN",
    45  		MANIFEST_INVALID:      "MANIFEST_INVALID",
    46  		MANIFEST_UNKNOWN:      "MANIFEST_UNKNOWN",
    47  		NAME_INVALID:          "NAME_INVALID",
    48  		NAME_UNKNOWN:          "NAME_UNKNOWN",
    49  		SIZE_INVALID:          "SIZE_INVALID",
    50  		UNAUTHORIZED:          "UNAUTHORIZED",
    51  		DENIED:                "DENIED",
    52  		UNSUPPORTED:           "UNSUPPORTED",
    53  		TOOMANYREQUESTS:       "TOOMANYREQUESTS",
    54  	}
    55  
    56  	return errMap[e]
    57  }
    58  
    59  func NewError(code ErrorCode) *Error {
    60  	errMap := map[ErrorCode]Error{
    61  		BLOB_UNKNOWN: {
    62  			Message: "blob unknown to registry",
    63  			Description: "blob unknown to registry 	This error MAY be returned when a blob is unknown " +
    64  				" to the registry in a specified repository. This can be returned with a standard get or " +
    65  				"if a manifest references an unknown layer during upload.",
    66  		},
    67  
    68  		BLOB_UPLOAD_INVALID: {
    69  			Message:     "blob upload invalid",
    70  			Description: "The blob upload encountered an error and can no longer proceed.",
    71  		},
    72  
    73  		BLOB_UPLOAD_UNKNOWN: {
    74  			Message:     "blob upload unknown to registry",
    75  			Description: "If a blob upload has been cancelled or was never started, this error code MAY be returned.",
    76  		},
    77  
    78  		DIGEST_INVALID: {
    79  			Message: "provided digest did not match uploaded content",
    80  			Description: "When a blob is uploaded, the registry will check that the content matches the " +
    81  				"digest provided by the client. The error MAY include a detail structure with the key " +
    82  				"\"digest\", including the invalid digest string. This error MAY also be returned when " +
    83  				"a manifest includes an invalid layer digest.",
    84  		},
    85  
    86  		MANIFEST_BLOB_UNKNOWN: {
    87  			Message:     "blob unknown to registry",
    88  			Description: "This error MAY be returned when a manifest blob is unknown to the registry.",
    89  		},
    90  
    91  		MANIFEST_INVALID: {
    92  			Message: "manifest invalid",
    93  			Description: "During upload, manifests undergo several checks ensuring " +
    94  				"validity. If those checks fail, this error MAY be returned, unless a more " +
    95  				"specific error is included. The detail will contain information the failed validation.",
    96  		},
    97  
    98  		MANIFEST_UNKNOWN: {
    99  			Message: "manifest unknown",
   100  			Description: "This error is returned when the manifest, identified by name " +
   101  				"and tag is unknown to the repository.",
   102  		},
   103  
   104  		NAME_INVALID: {
   105  			Message: "invalid repository name",
   106  			Description: "Invalid repository name encountered either during manifest " +
   107  				"validation or any API operation.",
   108  		},
   109  
   110  		NAME_UNKNOWN: {
   111  			Message:     "repository name not known to registry",
   112  			Description: "This is returned if the name used during an operation is unknown to the registry.",
   113  		},
   114  
   115  		SIZE_INVALID: {
   116  			Message: "provided length did not match content length",
   117  			Description: "When a layer is uploaded, the provided size will be checked against " +
   118  				"the uploaded content. If they do not match, this error will be returned.",
   119  		},
   120  
   121  		UNAUTHORIZED: {
   122  			Message: "authentication required",
   123  			Description: "The access controller was unable to authenticate the client. " +
   124  				"Often this will be accompanied by a WWW-Authenticate HTTP response header " +
   125  				"indicating how to authenticate.",
   126  		},
   127  
   128  		DENIED: {
   129  			Message:     "requested access to the resource is denied",
   130  			Description: "The access controller denied access for the operation on a resource.",
   131  		},
   132  
   133  		UNSUPPORTED: {
   134  			Message: "the operation is unsupported",
   135  			Description: "The operation was unsupported due to a missing " +
   136  				"implementation or invalid set of parameters.",
   137  		},
   138  
   139  		TOOMANYREQUESTS: {
   140  			Message:     "too many requests",
   141  			Description: "When a user or users has sent too many requests to the server within a given amount of time.",
   142  		},
   143  	}
   144  
   145  	err, ok := errMap[code]
   146  	if !ok {
   147  		panic(errors.ErrUnknownCode)
   148  	}
   149  
   150  	err.Code = code.String()
   151  	err.Detail = map[string]string{
   152  		"description": err.Description,
   153  	}
   154  
   155  	return &err
   156  }
   157  
   158  func (err *Error) AddDetail(m map[string]string) *Error {
   159  	for k, v := range m {
   160  		err.Detail[k] = v
   161  	}
   162  
   163  	return err
   164  }
   165  
   166  func NewErrorList(errors ...*Error) ErrorList {
   167  	var errList []*Error
   168  	errList = append(errList, errors...)
   169  
   170  	return ErrorList{errList}
   171  }