aboutsummaryrefslogtreecommitdiff
path: root/internal/engine/facts.go
diff options
context:
space:
mode:
Diffstat (limited to 'internal/engine/facts.go')
-rw-r--r--internal/engine/facts.go38
1 files changed, 30 insertions, 8 deletions
diff --git a/internal/engine/facts.go b/internal/engine/facts.go
index 89bd71b..641f1ef 100644
--- a/internal/engine/facts.go
+++ b/internal/engine/facts.go
@@ -5,6 +5,7 @@ package engine
import (
"context"
"errors"
+ "fmt"
"io/fs"
"path/filepath"
"sort"
@@ -83,18 +84,39 @@ func (run *matchRun) drainDupErrors() {
// PATH: cause", the path abbreviated like every other one shown, and an OS
// error's cause without the raw path it would repeat.
func dupWarning(err error) string {
+ return "duplicate: " + dupCause(err).Error()
+}
+
+// dupCause is a duplicate check's error as "PATH: cause", the path
+// shortened with xdg.Abbrev and not repeated inside the cause - a candidate
+// that could not be hashed, or an OS error on the file itself (plan 11
+// review L7). It still unwraps to err.
+func dupCause(err error) error {
+ path, cause := "", err
var ce dup.CandidateError
- if !errors.As(err, &ce) {
- return "duplicate: " + err.Error()
- }
- cause := ce.Err.Error()
var pe *fs.PathError
- if errors.As(ce.Err, &pe) {
- cause = pe.Op + ": " + pe.Err.Error()
+ switch {
+ case errors.As(err, &ce):
+ path, cause = ce.Path, ce.Err
+ if errors.As(ce.Err, &pe) {
+ cause = fmt.Errorf("%s: %w", pe.Op, pe.Err)
+ }
+ case errors.As(err, &pe):
+ path, cause = pe.Path, fmt.Errorf("%s: %w", pe.Op, pe.Err)
+ default:
+ return err
}
- return "duplicate: " + xdg.Abbrev(ce.Path) + ": " + cause
+ return shortenedErr{msg: xdg.Abbrev(path) + ": " + cause.Error(), err: err}
+}
+
+type shortenedErr struct {
+ msg string
+ err error
}
+func (e shortenedErr) Error() string { return e.msg }
+func (e shortenedErr) Unwrap() error { return e.err }
+
// dupIndex returns the shared *dup.Index for the resolved, sorted extra
// directories named by key, building it exactly once across every
// concurrent caller that asks for the same key.
@@ -263,7 +285,7 @@ func (f *facts) Duplicate(dirs []string) (string, bool, error) {
idx := f.run.dupIndex(key, sorted)
orig, isDup, err := idx.Lookup(f.file.Path)
if err != nil {
- return "", false, err
+ return "", false, dupCause(err)
}
if !isDup {
return "", false, nil