123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185 |
- package v2
- import (
- "fmt"
- "strings"
- )
- // ErrorCode represents the error type. The errors are serialized via strings
- // and the integer format may change and should *never* be exported.
- type ErrorCode int
- const (
- // ErrorCodeUnknown is a catch-all for errors not defined below.
- ErrorCodeUnknown ErrorCode = iota
- // ErrorCodeDigestInvalid is returned when uploading a blob if the
- // provided digest does not match the blob contents.
- ErrorCodeDigestInvalid
- // ErrorCodeSizeInvalid is returned when uploading a blob if the provided
- // size does not match the content length.
- ErrorCodeSizeInvalid
- // ErrorCodeNameInvalid is returned when the name in the manifest does not
- // match the provided name.
- ErrorCodeNameInvalid
- // ErrorCodeTagInvalid is returned when the tag in the manifest does not
- // match the provided tag.
- ErrorCodeTagInvalid
- // ErrorCodeNameUnknown when the repository name is not known.
- ErrorCodeNameUnknown
- // ErrorCodeManifestUnknown returned when image manifest is unknown.
- ErrorCodeManifestUnknown
- // ErrorCodeManifestInvalid returned when an image manifest is invalid,
- // typically during a PUT operation. This error encompasses all errors
- // encountered during manifest validation that aren't signature errors.
- ErrorCodeManifestInvalid
- // ErrorCodeManifestUnverified is returned when the manifest fails
- // signature verfication.
- ErrorCodeManifestUnverified
- // ErrorCodeBlobUnknown is returned when a blob is unknown to the
- // registry. This can happen when the manifest references a nonexistent
- // layer or the result is not found by a blob fetch.
- ErrorCodeBlobUnknown
- // ErrorCodeBlobUploadUnknown is returned when an upload is unknown.
- ErrorCodeBlobUploadUnknown
- )
- // ParseErrorCode attempts to parse the error code string, returning
- // ErrorCodeUnknown if the error is not known.
- func ParseErrorCode(s string) ErrorCode {
- desc, ok := idToDescriptors[s]
- if !ok {
- return ErrorCodeUnknown
- }
- return desc.Code
- }
- // Descriptor returns the descriptor for the error code.
- func (ec ErrorCode) Descriptor() ErrorDescriptor {
- d, ok := errorCodeToDescriptors[ec]
- if !ok {
- return ErrorCodeUnknown.Descriptor()
- }
- return d
- }
- // String returns the canonical identifier for this error code.
- func (ec ErrorCode) String() string {
- return ec.Descriptor().Value
- }
- // Message returned the human-readable error message for this error code.
- func (ec ErrorCode) Message() string {
- return ec.Descriptor().Message
- }
- // MarshalText encodes the receiver into UTF-8-encoded text and returns the
- // result.
- func (ec ErrorCode) MarshalText() (text []byte, err error) {
- return []byte(ec.String()), nil
- }
- // UnmarshalText decodes the form generated by MarshalText.
- func (ec *ErrorCode) UnmarshalText(text []byte) error {
- desc, ok := idToDescriptors[string(text)]
- if !ok {
- desc = ErrorCodeUnknown.Descriptor()
- }
- *ec = desc.Code
- return nil
- }
- // Error provides a wrapper around ErrorCode with extra Details provided.
- type Error struct {
- Code ErrorCode `json:"code"`
- Message string `json:"message,omitempty"`
- Detail interface{} `json:"detail,omitempty"`
- }
- // Error returns a human readable representation of the error.
- func (e Error) Error() string {
- return fmt.Sprintf("%s: %s",
- strings.ToLower(strings.Replace(e.Code.String(), "_", " ", -1)),
- e.Message)
- }
- // Errors provides the envelope for multiple errors and a few sugar methods
- // for use within the application.
- type Errors struct {
- Errors []Error `json:"errors,omitempty"`
- }
- // Push pushes an error on to the error stack, with the optional detail
- // argument. It is a programming error (ie panic) to push more than one
- // detail at a time.
- func (errs *Errors) Push(code ErrorCode, details ...interface{}) {
- if len(details) > 1 {
- panic("please specify zero or one detail items for this error")
- }
- var detail interface{}
- if len(details) > 0 {
- detail = details[0]
- }
- if err, ok := detail.(error); ok {
- detail = err.Error()
- }
- errs.PushErr(Error{
- Code: code,
- Message: code.Message(),
- Detail: detail,
- })
- }
- // PushErr pushes an error interface onto the error stack.
- func (errs *Errors) PushErr(err error) {
- switch err.(type) {
- case Error:
- errs.Errors = append(errs.Errors, err.(Error))
- default:
- errs.Errors = append(errs.Errors, Error{Message: err.Error()})
- }
- }
- func (errs *Errors) Error() string {
- switch errs.Len() {
- case 0:
- return "<nil>"
- case 1:
- return errs.Errors[0].Error()
- default:
- msg := "errors:\n"
- for _, err := range errs.Errors {
- msg += err.Error() + "\n"
- }
- return msg
- }
- }
- // Clear clears the errors.
- func (errs *Errors) Clear() {
- errs.Errors = errs.Errors[:0]
- }
- // Len returns the current number of errors.
- func (errs *Errors) Len() int {
- return len(errs.Errors)
- }
|