mirror of
				https://gitea.com/Lydanne/buildx.git
				synced 2025-11-04 18:13:42 +08:00 
			
		
		
		
	
		
			
				
	
	
		
			148 lines
		
	
	
		
			3.6 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			148 lines
		
	
	
		
			3.6 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
/*
 | 
						|
   Copyright The containerd Authors.
 | 
						|
 | 
						|
   Licensed under the Apache License, Version 2.0 (the "License");
 | 
						|
   you may not use this file except in compliance with the License.
 | 
						|
   You may obtain a copy of the License at
 | 
						|
 | 
						|
       http://www.apache.org/licenses/LICENSE-2.0
 | 
						|
 | 
						|
   Unless required by applicable law or agreed to in writing, software
 | 
						|
   distributed under the License is distributed on an "AS IS" BASIS,
 | 
						|
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
						|
   See the License for the specific language governing permissions and
 | 
						|
   limitations under the License.
 | 
						|
*/
 | 
						|
 | 
						|
package errdefs
 | 
						|
 | 
						|
import "context"
 | 
						|
 | 
						|
// Resolve returns the first error found in the error chain which matches an
 | 
						|
// error defined in this package or context error. A raw, unwrapped error is
 | 
						|
// returned or ErrUnknown if no matching error is found.
 | 
						|
//
 | 
						|
// This is useful for determining a response code based on the outermost wrapped
 | 
						|
// error rather than the original cause. For example, a not found error deep
 | 
						|
// in the code may be wrapped as an invalid argument. When determining status
 | 
						|
// code from Is* functions, the depth or ordering of the error is not
 | 
						|
// considered.
 | 
						|
//
 | 
						|
// The search order is depth first, a wrapped error returned from any part of
 | 
						|
// the chain from `Unwrap() error` will be returned before any joined errors
 | 
						|
// as returned by `Unwrap() []error`.
 | 
						|
func Resolve(err error) error {
 | 
						|
	if err == nil {
 | 
						|
		return nil
 | 
						|
	}
 | 
						|
	err = firstError(err)
 | 
						|
	if err == nil {
 | 
						|
		err = ErrUnknown
 | 
						|
	}
 | 
						|
	return err
 | 
						|
}
 | 
						|
 | 
						|
func firstError(err error) error {
 | 
						|
	for {
 | 
						|
		switch err {
 | 
						|
		case ErrUnknown,
 | 
						|
			ErrInvalidArgument,
 | 
						|
			ErrNotFound,
 | 
						|
			ErrAlreadyExists,
 | 
						|
			ErrPermissionDenied,
 | 
						|
			ErrResourceExhausted,
 | 
						|
			ErrFailedPrecondition,
 | 
						|
			ErrConflict,
 | 
						|
			ErrNotModified,
 | 
						|
			ErrAborted,
 | 
						|
			ErrOutOfRange,
 | 
						|
			ErrNotImplemented,
 | 
						|
			ErrInternal,
 | 
						|
			ErrUnavailable,
 | 
						|
			ErrDataLoss,
 | 
						|
			ErrUnauthenticated,
 | 
						|
			context.DeadlineExceeded,
 | 
						|
			context.Canceled:
 | 
						|
			return err
 | 
						|
		}
 | 
						|
		switch e := err.(type) {
 | 
						|
		case customMessage:
 | 
						|
			err = e.err
 | 
						|
		case unknown:
 | 
						|
			return ErrUnknown
 | 
						|
		case invalidParameter:
 | 
						|
			return ErrInvalidArgument
 | 
						|
		case notFound:
 | 
						|
			return ErrNotFound
 | 
						|
		case alreadyExists:
 | 
						|
			return ErrAlreadyExists
 | 
						|
		case forbidden:
 | 
						|
			return ErrPermissionDenied
 | 
						|
		case resourceExhausted:
 | 
						|
			return ErrResourceExhausted
 | 
						|
		case failedPrecondition:
 | 
						|
			return ErrFailedPrecondition
 | 
						|
		case conflict:
 | 
						|
			return ErrConflict
 | 
						|
		case notModified:
 | 
						|
			return ErrNotModified
 | 
						|
		case aborted:
 | 
						|
			return ErrAborted
 | 
						|
		case errOutOfRange:
 | 
						|
			return ErrOutOfRange
 | 
						|
		case notImplemented:
 | 
						|
			return ErrNotImplemented
 | 
						|
		case system:
 | 
						|
			return ErrInternal
 | 
						|
		case unavailable:
 | 
						|
			return ErrUnavailable
 | 
						|
		case dataLoss:
 | 
						|
			return ErrDataLoss
 | 
						|
		case unauthorized:
 | 
						|
			return ErrUnauthenticated
 | 
						|
		case deadlineExceeded:
 | 
						|
			return context.DeadlineExceeded
 | 
						|
		case cancelled:
 | 
						|
			return context.Canceled
 | 
						|
		case interface{ Unwrap() error }:
 | 
						|
			err = e.Unwrap()
 | 
						|
			if err == nil {
 | 
						|
				return nil
 | 
						|
			}
 | 
						|
		case interface{ Unwrap() []error }:
 | 
						|
			for _, ue := range e.Unwrap() {
 | 
						|
				if fe := firstError(ue); fe != nil {
 | 
						|
					return fe
 | 
						|
				}
 | 
						|
			}
 | 
						|
			return nil
 | 
						|
		case interface{ Is(error) bool }:
 | 
						|
			for _, target := range []error{ErrUnknown,
 | 
						|
				ErrInvalidArgument,
 | 
						|
				ErrNotFound,
 | 
						|
				ErrAlreadyExists,
 | 
						|
				ErrPermissionDenied,
 | 
						|
				ErrResourceExhausted,
 | 
						|
				ErrFailedPrecondition,
 | 
						|
				ErrConflict,
 | 
						|
				ErrNotModified,
 | 
						|
				ErrAborted,
 | 
						|
				ErrOutOfRange,
 | 
						|
				ErrNotImplemented,
 | 
						|
				ErrInternal,
 | 
						|
				ErrUnavailable,
 | 
						|
				ErrDataLoss,
 | 
						|
				ErrUnauthenticated,
 | 
						|
				context.DeadlineExceeded,
 | 
						|
				context.Canceled} {
 | 
						|
				if e.Is(target) {
 | 
						|
					return target
 | 
						|
				}
 | 
						|
			}
 | 
						|
			return nil
 | 
						|
		default:
 | 
						|
			return nil
 | 
						|
		}
 | 
						|
	}
 | 
						|
}
 |