rclone: return rclone error instead of canceled context

When rclone fails during the connection setup this currently often
results in a context canceled error. Replace this error with the exit
code from rclone.
This commit is contained in:
Michael Eischer 2022-09-22 21:52:18 +02:00
parent f9d4e0c2af
commit b8acad4da0
2 changed files with 23 additions and 1 deletions

View File

@ -13,6 +13,7 @@ import (
"os"
"os/exec"
"sync"
"syscall"
"time"
"github.com/cenkalti/backoff/v4"
@ -244,7 +245,15 @@ func newBackend(cfg Config, lim limiter.Limiter) (*Backend, error) {
// ignore subsequent errors
_ = bg()
_ = cmd.Process.Kill()
return nil, errors.Errorf("error talking HTTP to rclone: %v", err)
// wait for rclone to exit
wg.Wait()
// try to return the program exit code if communication with rclone has failed
if be.waitResult != nil && (err == context.Canceled || errors.Is(err, io.ErrUnexpectedEOF) || errors.Is(err, syscall.EPIPE)) {
err = be.waitResult
}
return nil, fmt.Errorf("error talking HTTP to rclone: %w", err)
}
debug.Log("HTTP status %q returned, moving instance to background", res.Status)

View File

@ -41,3 +41,16 @@ func TestRcloneExit(t *testing.T) {
rtest.Assert(t, err != nil, "expected an error")
}
}
// restic should detect rclone startup failures
func TestRcloneFailedStart(t *testing.T) {
cfg := NewConfig()
// exits with exit code 1
cfg.Program = "false"
_, err := Open(cfg, nil)
var e *exec.ExitError
if !errors.As(err, &e) {
// unexpected error
rtest.OK(t, err)
}
}