func()

in error.go [411:508]


func (b *exceptionDataBuilder) init(e *exceptionData, err error) bool {
	b.errorCount++
	reflectValue := reflect.ValueOf(err)
	reflectType := reflectValue.Type()
	switch reflectType.Kind() {
	case reflect.Chan, reflect.Func, reflect.Map, reflect.Ptr, reflect.Slice, reflect.UnsafePointer:
		// Prevent infinite recursion due to cyclic error causes.
		ptrVal := reflectValue.Pointer()
		if b.pointerErrors == nil {
			b.pointerErrors = map[uintptr]struct{}{ptrVal: struct{}{}}
		} else {
			if _, ok := b.pointerErrors[ptrVal]; ok {
				return false
			}
			b.pointerErrors[ptrVal] = struct{}{}
		}
	}

	e.message = truncateString(err.Error())
	if e.message == "" {
		e.message = "[EMPTY]"
	}

	namedType := reflectType
	if reflectType.Name() == "" && reflectType.Kind() == reflect.Ptr {
		namedType = reflectType.Elem()
	}
	e.Type.Name = namedType.Name()
	e.Type.PackagePath = namedType.PkgPath()

	// If the error implements Type, use that to
	// override the type name determined through
	// reflection.
	if err, ok := err.(interface {
		Type() string
	}); ok {
		e.Type.Name = err.Type()
	}

	// If the error implements a Code method, use
	// that to set the exception code.
	switch err := err.(type) {
	case interface {
		Code() string
	}:
		e.Code.String = err.Code()
	case interface {
		Code() float64
	}:
		e.Code.Number = err.Code()
	}

	// If the error implements an Unwrap or Cause method, use that to set the cause error.
	// Unwrap is defined by errors wrapped using fmt.Errorf, while Cause is defined by
	// errors wrapped using pkg/errors.Wrap.
	switch err := err.(type) {
	case interface{ Unwrap() error }:
		if cause := err.Unwrap(); cause != nil {
			e.ErrorDetails.Cause = append(e.ErrorDetails.Cause, cause)
		}
	case interface{ Unwrap() []error }:
		if causes := err.Unwrap(); causes != nil {
			for _, cause := range causes {
				if cause != nil {
					e.ErrorDetails.Cause = append(e.ErrorDetails.Cause, cause)
				}
			}
		}
	case interface{ Cause() error }:
		if cause := err.Cause(); cause != nil {
			e.ErrorDetails.Cause = append(e.ErrorDetails.Cause, cause)
		}
	}

	// Run registered ErrorDetailers over the error.
	for _, ed := range typeErrorDetailers[reflectType] {
		ed.ErrorDetails(err, &e.ErrorDetails)
	}
	for _, ed := range errorDetailers {
		ed.ErrorDetails(err, &e.ErrorDetails)
	}

	e.Code.String = truncateString(e.Code.String)
	e.Type.Name = truncateString(e.Type.Name)
	e.Type.PackagePath = truncateString(e.Type.PackagePath)
	e.stacktrace = stacktrace.AppendErrorStacktrace(e.stacktrace, err, b.stackTraceLimit)

	for _, err := range e.ErrorDetails.Cause {
		if b.errorCount >= maxErrorTreeNodes {
			break
		}
		var data exceptionData
		if b.init(&data, err) {
			e.cause = append(e.cause, data)
		}
	}
	return true
}