fix: extend ignore404Error to match 404 Not Found string from S3 sink… (#8741)

* fix: extend ignore404Error to match 404 Not Found string from S3 sink errors

* test: add unit tests for isIgnorable404 error matching

* improve: pre-compute ignorable 404 string and simplify isIgnorable404

* test: replace init() with TestMain for global HTTP client setup
This commit is contained in:
Mmx233
2026-03-23 11:59:34 -07:00
committed by GitHub
parent 156e1a6e64
commit ecadeddcbe
2 changed files with 93 additions and 9 deletions

View File

@@ -3,6 +3,7 @@ package command
import (
"errors"
"fmt"
nethttp "net/http"
"regexp"
"strings"
"time"
@@ -33,7 +34,8 @@ type FilerBackupOptions struct {
}
var (
filerBackupOptions FilerBackupOptions
filerBackupOptions FilerBackupOptions
ignorable404ErrString = fmt.Sprintf("%d %s: %s", nethttp.StatusNotFound, nethttp.StatusText(nethttp.StatusNotFound), http.ErrNotFound.Error())
)
func init() {
@@ -144,17 +146,10 @@ func doFilerBackup(grpcDialOption grpc.DialOption, backupOption *FilerBackupOpti
if err == nil {
return nil
}
// ignore HTTP 404 from remote reads
if errors.Is(err, http.ErrNotFound) {
if isIgnorable404(err) {
glog.V(0).Infof("got 404 error for %s, ignore it: %s", getSourceKey(resp), err.Error())
return nil
}
// also ignore missing volume/lookup errors coming from LookupFileId or vid map
errStr := err.Error()
if strings.Contains(errStr, "LookupFileId") || (strings.Contains(errStr, "volume id") && strings.Contains(errStr, "not found")) {
glog.V(0).Infof("got missing-volume error for %s, ignore it: %s", getSourceKey(resp), errStr)
return nil
}
return err
}
} else {
@@ -218,3 +213,19 @@ func getSourceKey(resp *filer_pb.SubscribeMetadataResponse) string {
}
return ""
}
// isIgnorable404 returns true if the error represents a 404/not-found condition
// that should be silently ignored during backup. This covers:
// - errors wrapping http.ErrNotFound (direct volume server 404 via non-S3 sinks)
// - errors containing the "404 Not Found: not found" status string (S3 sink path
// where AWS SDK breaks the errors.Is unwrap chain)
// - LookupFileId or volume-id-not-found errors from the volume id map
func isIgnorable404(err error) bool {
if errors.Is(err, http.ErrNotFound) {
return true
}
errStr := err.Error()
return strings.Contains(errStr, ignorable404ErrString) ||
strings.Contains(errStr, "LookupFileId") ||
(strings.Contains(errStr, "volume id") && strings.Contains(errStr, "not found"))
}