internal/worker: explicitly capture OOMs

Change-Id: I837a8b4a82f5ee28bdb6981f923437c25f8109ae
Reviewed-on: https://go-review.googlesource.com/c/pkgsite-metrics/+/543856
Reviewed-by: Maceo Thompson <maceothompson@google.com>
Run-TryBot: Zvonimir Pavlinovic <zpavlinovic@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
diff --git a/internal/worker/analysis.go b/internal/worker/analysis.go
index 8fd820b..4ee0b73 100644
--- a/internal/worker/analysis.go
+++ b/internal/worker/analysis.go
@@ -226,6 +226,8 @@
 			err = fmt.Errorf("%v: %w", err, derrors.LoadVendorError)
 		case isProxyCacheMiss(err):
 			err = fmt.Errorf("%v: %w", err, derrors.ProxyError)
+		case isMemoryIssue(err):
+			err = fmt.Errorf("%v: %w", err, derrors.ScanModuleMemoryLimitExceeded)
 		case isBuildIssue(err):
 			err = fmt.Errorf("%v: %w", err, derrors.LoadPackagesError)
 		case !hasGoMod:
diff --git a/internal/worker/govulncheck_scan.go b/internal/worker/govulncheck_scan.go
index 6cbe1fc..c8e48f6 100644
--- a/internal/worker/govulncheck_scan.go
+++ b/internal/worker/govulncheck_scan.go
@@ -369,6 +369,8 @@
 			err = fmt.Errorf("%v: %w", err, derrors.ScanModuleTooManyOpenFiles)
 		case isProxyCacheMiss(err):
 			err = fmt.Errorf("%v: %w", err, derrors.ProxyError)
+		case isMemoryIssue(err):
+			err = fmt.Errorf("%v: %w", err, derrors.ScanModuleMemoryLimitExceeded)
 		default:
 			err = fmt.Errorf("%v: %w", err, derrors.ScanModuleGovulncheckError)
 		}
diff --git a/internal/worker/scan.go b/internal/worker/scan.go
index 63bcd8d..9c4ba0e 100644
--- a/internal/worker/scan.go
+++ b/internal/worker/scan.go
@@ -367,3 +367,7 @@
 		strings.Contains(errStr, "but was required") ||
 		strings.Contains(errStr, "relative import paths are not supported in module mode")
 }
+
+func isMemoryIssue(err error) bool {
+	return strings.Contains(err.Error(), "status 137")
+}