internal/worker: keep going on module scan failure
If a module can't be scanned (because, for example, its packages can't
be loaded), continue scanning other modules.
Change-Id: I0e79d4083fb4bd2a1f158b38593c81832a36c255
Reviewed-on: https://go-review.googlesource.com/c/vulndb/+/393836
Trust: Jonathan Amsterdam <jba@google.com>
Run-TryBot: Jonathan Amsterdam <jba@google.com>
Reviewed-by: Julie Qiu <julie@golang.org>
TryBot-Result: Gopher Robot <gobot@golang.org>
diff --git a/internal/worker/scan_modules.go b/internal/worker/scan_modules.go
index 79ca291..8d0981c 100644
--- a/internal/worker/scan_modules.go
+++ b/internal/worker/scan_modules.go
@@ -7,6 +7,7 @@
import (
"archive/zip"
"context"
+ "errors"
"fmt"
"io"
"os"
@@ -36,6 +37,18 @@
"golang.org/x/vuln", "golang.org/x/vulndb", "golang.org/x/website",
}
+type scanError struct {
+ err error
+}
+
+func (s scanError) Error() string {
+ return s.err.Error()
+}
+
+func (s scanError) Unwrap() error {
+ return s.err
+}
+
// ScanModules scans a list of Go modules for vulnerabilities.
// It assumes the root of each repo is a module, and there are no nested modules.
func ScanModules(ctx context.Context, st store.Store, force bool) error {
@@ -50,7 +63,10 @@
return err
}
if err := processModule(ctx, modulePath, latest, dbClient, st, force); err != nil {
- return err
+ if errors.As(err, new(scanError)) {
+ return err
+ }
+ // Otherwise, if the error was in the scanning itself, keep going.
}
latestTagged, err := latestTaggedVersion(ctx, modulePath)
if err != nil {
@@ -88,7 +104,7 @@
return err2
}
if err != nil {
- return err
+ return scanError{err}
}
log.Infof(ctx, "%s@%s has %d vulns", modulePath, version, len(res.Vulns))
for _, v := range res.Vulns {
diff --git a/internal/worker/scan_modules_test.go b/internal/worker/scan_modules_test.go
index 82296c7..f53b77d 100644
--- a/internal/worker/scan_modules_test.go
+++ b/internal/worker/scan_modules_test.go
@@ -6,7 +6,9 @@
import (
"context"
+ "errors"
"flag"
+ "io"
"os"
"testing"
@@ -31,6 +33,16 @@
}
}
+func TestAsScanError(t *testing.T) {
+ check := func(err error, want bool) {
+ if got := errors.As(err, new(scanError)); got != want {
+ t.Errorf("%T: got %t, want %t", err, got, want)
+ }
+ }
+ check(io.EOF, false)
+ check(scanError{io.EOF}, true)
+}
+
func TestScanModule(t *testing.T) {
ctx := event.WithExporter(context.Background(),
event.NewExporter(log.NewLineHandler(os.Stderr), nil))