Team Ai
Datasetpublic

codekingpro/portable-devtools

sourceHugging Faceupdated 5mo agoView on Hugging Face
1likes14kdownloads
wrap.go210 linesDownload Raw Back to errors
1// Copyright 2018 The Go Authors. All rights reserved.2// Use of this source code is governed by a BSD-style3// license that can be found in the LICENSE file.4 5package errors6 7import (8	"internal/reflectlite"9)10 11// Unwrap returns the result of calling the Unwrap method on err, if err's12// type contains an Unwrap method returning error.13// Otherwise, Unwrap returns nil.14//15// Unwrap only calls a method of the form "Unwrap() error".16// In particular Unwrap does not unwrap errors returned by [Join].17func Unwrap(err error) error {18	u, ok := err.(interface {19		Unwrap() error20	})21	if !ok {22		return nil23	}24	return u.Unwrap()25}26 27// Is reports whether any error in err's tree matches target.28// The target must be comparable.29//30// The tree consists of err itself, followed by the errors obtained by repeatedly31// calling its Unwrap() error or Unwrap() []error method. When err wraps multiple32// errors, Is examines err followed by a depth-first traversal of its children.33//34// An error is considered to match a target if it is equal to that target or if35// it implements a method Is(error) bool such that Is(target) returns true.36//37// An error type might provide an Is method so it can be treated as equivalent38// to an existing error. For example, if MyError defines39//40//	func (m MyError) Is(target error) bool { return target == fs.ErrExist }41//42// then Is(MyError{}, fs.ErrExist) returns true. See [syscall.Errno.Is] for43// an example in the standard library. An Is method should only shallowly44// compare err and the target and not call [Unwrap] on either.45func Is(err, target error) bool {46	if err == nil || target == nil {47		return err == target48	}49 50	isComparable := reflectlite.TypeOf(target).Comparable()51	return is(err, target, isComparable)52}53 54func is(err, target error, targetComparable bool) bool {55	for {56		if targetComparable && err == target {57			return true58		}59		if x, ok := err.(interface{ Is(error) bool }); ok && x.Is(target) {60			return true61		}62		switch x := err.(type) {63		case interface{ Unwrap() error }:64			err = x.Unwrap()65			if err == nil {66				return false67			}68		case interface{ Unwrap() []error }:69			for _, err := range x.Unwrap() {70				if is(err, target, targetComparable) {71					return true72				}73			}74			return false75		default:76			return false77		}78	}79}80 81// As finds the first error in err's tree that matches target, and if one is found, sets82// target to that error value and returns true. Otherwise, it returns false.83//84// For most uses, prefer [AsType]. As is equivalent to [AsType] but sets its target85// argument rather than returning the matching error and doesn't require its target86// argument to implement error.87//88// The tree consists of err itself, followed by the errors obtained by repeatedly89// calling its Unwrap() error or Unwrap() []error method. When err wraps multiple90// errors, As examines err followed by a depth-first traversal of its children.91//92// An error matches target if the error's concrete value is assignable to the value93// pointed to by target, or if the error has a method As(any) bool such that94// As(target) returns true. In the latter case, the As method is responsible for95// setting target.96//97// An error type might provide an As method so it can be treated as if it were a98// different error type.99//100// As panics if target is not a non-nil pointer to either a type that implements101// error, or to any interface type.102func As(err error, target any) bool {103	if err == nil {104		return false105	}106	if target == nil {107		panic("errors: target cannot be nil")108	}109	val := reflectlite.ValueOf(target)110	typ := val.Type()111	if typ.Kind() != reflectlite.Ptr || val.IsNil() {112		panic("errors: target must be a non-nil pointer")113	}114	targetType := typ.Elem()115	if targetType.Kind() != reflectlite.Interface && !targetType.Implements(errorType) {116		panic("errors: *target must be interface or implement error")117	}118	return as(err, target, val, targetType)119}120 121func as(err error, target any, targetVal reflectlite.Value, targetType reflectlite.Type) bool {122	for {123		if reflectlite.TypeOf(err).AssignableTo(targetType) {124			targetVal.Elem().Set(reflectlite.ValueOf(err))125			return true126		}127		if x, ok := err.(interface{ As(any) bool }); ok && x.As(target) {128			return true129		}130		switch x := err.(type) {131		case interface{ Unwrap() error }:132			err = x.Unwrap()133			if err == nil {134				return false135			}136		case interface{ Unwrap() []error }:137			for _, err := range x.Unwrap() {138				if err == nil {139					continue140				}141				if as(err, target, targetVal, targetType) {142					return true143				}144			}145			return false146		default:147			return false148		}149	}150}151 152var errorType = reflectlite.TypeOf((*error)(nil)).Elem()153 154// AsType finds the first error in err's tree that matches the type E, and155// if one is found, returns that error value and true. Otherwise, it156// returns the zero value of E and false.157//158// The tree consists of err itself, followed by the errors obtained by159// repeatedly calling its Unwrap() error or Unwrap() []error method. When160// err wraps multiple errors, AsType examines err followed by a161// depth-first traversal of its children.162//163// An error err matches the type E if the type assertion err.(E) holds,164// or if the error has a method As(any) bool such that err.As(target)165// returns true when target is a non-nil *E. In the latter case, the As166// method is responsible for setting target.167func AsType[E error](err error) (E, bool) {168	if err == nil {169		var zero E170		return zero, false171	}172	var pe *E // lazily initialized173	return asType(err, &pe)174}175 176func asType[E error](err error, ppe **E) (_ E, _ bool) {177	for {178		if e, ok := err.(E); ok {179			return e, true180		}181		if x, ok := err.(interface{ As(any) bool }); ok {182			if *ppe == nil {183				*ppe = new(E)184			}185			if x.As(*ppe) {186				return **ppe, true187			}188		}189		switch x := err.(type) {190		case interface{ Unwrap() error }:191			err = x.Unwrap()192			if err == nil {193				return194			}195		case interface{ Unwrap() []error }:196			for _, err := range x.Unwrap() {197				if err == nil {198					continue199				}200				if x, ok := asType(err, ppe); ok {201					return x, true202				}203			}204			return205		default:206			return207		}208	}209}210 
codekingpro/portable-devtools · Team Ai