diff --git a/cmd/serve/restic/restic.go b/cmd/serve/restic/restic.go index be56fe947..396ef1ebf 100644 --- a/cmd/serve/restic/restic.go +++ b/cmd/serve/restic/restic.go @@ -341,7 +341,11 @@ func (s *server) serveObject(w http.ResponseWriter, r *http.Request) { o, err := s.newObject(r.Context(), remote) if err != nil { fs.Debugf(remote, "%s request error: %v", r.Method, err) - http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound) + if errors.Is(err, fs.ErrorObjectNotFound) { + http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound) + } else { + http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) + } return } serve.Object(w, r, o) @@ -404,7 +408,7 @@ func (s *server) deleteObject(w http.ResponseWriter, r *http.Request) { if err := o.Remove(r.Context()); err != nil { fs.Errorf(remote, "Delete request remove error: %v", err) - if err == fs.ErrorObjectNotFound { + if errors.Is(err, fs.ErrorObjectNotFound) { http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound) } else { http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) @@ -466,7 +470,7 @@ func (s *server) listObjects(w http.ResponseWriter, r *http.Request) { if err != nil { if !errors.Is(err, fs.ErrorDirNotFound) { fs.Errorf(remote, "list failed: %#v %T", err, err) - http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound) + http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) return } } diff --git a/cmd/serve/restic/restic_test.go b/cmd/serve/restic/restic_test.go index 3db040bdd..36d09f93c 100644 --- a/cmd/serve/restic/restic_test.go +++ b/cmd/serve/restic/restic_test.go @@ -5,6 +5,7 @@ package restic import ( "context" + "errors" "net/http" "net/http/httptest" "os" @@ -12,6 +13,8 @@ import ( "testing" _ "github.com/rclone/rclone/backend/all" + "github.com/rclone/rclone/cmd" + "github.com/rclone/rclone/fs" "github.com/rclone/rclone/fstest" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -114,3 +117,56 @@ func TestMakeRemote(t *testing.T) { got.ServeHTTP(w, r) } } + +type listErrorFs struct { + fs.Fs +} + +func (f *listErrorFs) List(ctx context.Context, dir string) (entries fs.DirEntries, err error) { + return fs.DirEntries{}, errors.New("oops") +} + +func TestListErrors(t *testing.T) { + ctx := context.Background() + // setup rclone with a local backend in a temporary directory + tempdir := t.TempDir() + opt := newOpt() + + // make a new file system in the temp dir + f := &listErrorFs{Fs: cmd.NewFsSrc([]string{tempdir})} + s, err := newServer(ctx, f, &opt) + require.NoError(t, err) + router := s.Server.Router() + + req := newRequest(t, "GET", "/test/snapshots/", nil) + checkRequest(t, router.ServeHTTP, req, []wantFunc{wantCode(http.StatusInternalServerError)}) +} + +type newObjectErrorFs struct { + fs.Fs + err error +} + +func (f *newObjectErrorFs) NewObject(ctx context.Context, remote string) (fs.Object, error) { + return nil, f.err +} + +func TestServeErrors(t *testing.T) { + ctx := context.Background() + // setup rclone with a local backend in a temporary directory + tempdir := t.TempDir() + opt := newOpt() + + // make a new file system in the temp dir + f := &newObjectErrorFs{Fs: cmd.NewFsSrc([]string{tempdir})} + s, err := newServer(ctx, f, &opt) + require.NoError(t, err) + router := s.Server.Router() + + f.err = errors.New("oops") + req := newRequest(t, "GET", "/test/config", nil) + checkRequest(t, router.ServeHTTP, req, []wantFunc{wantCode(http.StatusInternalServerError)}) + + f.err = fs.ErrorObjectNotFound + checkRequest(t, router.ServeHTTP, req, []wantFunc{wantCode(http.StatusNotFound)}) +}