github.com/anchore/syft@v1.38.2/internal/cache/error_resolver.go (about)

     1  package cache
     2  
     3  import "fmt"
     4  
     5  // GetResolverCachingErrors returns a Resolver that caches errors and will return them
     6  // instead of continuing to call the provided resolve functions
     7  func GetResolverCachingErrors[T any](name, version string) Resolver[T] {
     8  	return &errorResolver[T]{
     9  		resolver: GetResolver[errResponse[T]](name, version),
    10  	}
    11  }
    12  
    13  type errResponse[T any] struct {
    14  	Error string `json:"err,omitempty"`
    15  	Value T      `json:"val,omitempty"`
    16  }
    17  
    18  type errorResolver[T any] struct {
    19  	resolver Resolver[errResponse[T]]
    20  }
    21  
    22  func (r *errorResolver[T]) Resolve(key string, resolver resolverFunc[T]) (T, error) {
    23  	v, err := r.resolver.Resolve(key, func() (errResponse[T], error) {
    24  		v, err := resolver()
    25  		out := errResponse[T]{
    26  			Value: v,
    27  		}
    28  		if err != nil {
    29  			out.Error = err.Error()
    30  		}
    31  		return out, nil
    32  	})
    33  	if err != nil {
    34  		return v.Value, err
    35  	}
    36  	if v.Error != "" {
    37  		return v.Value, fmt.Errorf("failed to resolve cache: %s", v.Error)
    38  	}
    39  	return v.Value, nil
    40  }