Fixed #215: Better error handling in resolver to catch recursions
diff --git a/dependency/resolver.go b/dependency/resolver.go
index 1427670..0d0e3c4 100644
--- a/dependency/resolver.go
+++ b/dependency/resolver.go
@@ -138,6 +138,9 @@
// Items already in the queue.
alreadyQ map[string]bool
+ // Attempts to scan that had unrecoverable error.
+ hadError map[string]bool
+
basedir string
seen map[string]bool
@@ -174,6 +177,7 @@
BuildContext: buildContext,
seen: map[string]bool{},
alreadyQ: map[string]bool{},
+ hadError: map[string]bool{},
findCache: map[string]*PkgInfo{},
// The config instance here should really be replaced with a real one.
@@ -347,6 +351,13 @@
r.alreadyQ[dep] = true
+ // If we've already encountered an error processing this dependency
+ // skip it.
+ _, foundErr := r.hadError[dep]
+ if foundErr {
+ continue
+ }
+
// Skip ignored packages
if r.Config.HasIgnore(dep) {
msg.Info("Ignoring: %s", dep)
@@ -359,23 +370,37 @@
pkg, err := r.BuildContext.ImportDir(vdep, 0)
if err != nil {
msg.Debug("ImportDir error on %s: %s", vdep, err)
+ _, foundQ := r.alreadyQ[dep]
if strings.HasPrefix(err.Error(), "no buildable Go source") {
msg.Debug("No subpackages declared. Skipping %s.", dep)
continue
- }
- if ok, err := r.Handler.NotFound(dep); ok {
- r.alreadyQ[dep] = true
+ } else if os.IsNotExist(err) && !foundErr && !foundQ {
+ // If the location doesn't exist, there hasn't already been an
+ // error, it's not already been in the Q then try to fetch it.
+ // When there's an error or it's already in the Q (it should be
+ // fetched if it's marked in r.alreadyQ) we skip to make sure
+ // not to get stuck in a recursion.
- // By adding to the queue it will get reprocessed now that
- // it exists.
- queue.PushBack(r.vpath(dep))
- r.VersionHandler.SetVersion(dep)
- } else if err != nil {
- msg.Error("Error looking for %s: %s", dep, err)
+ // If the location doesn't exist try to fetch it.
+ if ok, err2 := r.Handler.NotFound(dep); ok {
+ r.alreadyQ[dep] = true
+
+ // By adding to the queue it will get reprocessed now that
+ // it exists.
+ queue.PushBack(r.vpath(dep))
+ r.VersionHandler.SetVersion(dep)
+ } else if err2 != nil {
+ r.hadError[dep] = true
+ msg.Error("Error looking for %s: %s", dep, err2)
+ } else {
+ r.hadError[dep] = true
+ // TODO (mpb): Should we toss this into a Handler to
+ // see if this is on GOPATH and copy it?
+ msg.Info("Not found in vendor/: %s (1)", dep)
+ }
} else {
- // TODO (mpb): Should we toss this into a Handler to
- // see if this is on GOPATH and copy it?
- msg.Info("Not found in vendor/: %s (1)", dep)
+ r.hadError[dep] = true
+ msg.Error("Error scanning %s: %s", dep, err)
}
continue
}
@@ -408,8 +433,10 @@
queue.PushBack(r.vpath(imp))
r.VersionHandler.SetVersion(imp)
} else if err != nil {
+ r.hadError[dep] = true
msg.Warn("Error looking for %s: %s", imp, err)
} else {
+ r.hadError[dep] = true
msg.Info("Not found: %s (2)", imp)
}
case LocGopath: