From: Matt Joiner Date: Wed, 28 Feb 2024 04:47:31 +0000 (+1100) Subject: cmd/torrent download: Propagate write errors X-Git-Tag: v1.55.0~2 X-Git-Url: http://www.git.stargrave.org/?a=commitdiff_plain;h=b8e03eb8583e2f0385ab8237dda491b8a64ad957;p=btrtrc.git cmd/torrent download: Propagate write errors --- diff --git a/cmd/torrent/download.go b/cmd/torrent/download.go index 065ea2ad..1fc4759f 100644 --- a/cmd/torrent/download.go +++ b/cmd/torrent/download.go @@ -89,7 +89,13 @@ func resolveTestPeers(addrs []string) (ret []torrent.PeerInfo) { return } -func addTorrents(ctx context.Context, client *torrent.Client, flags downloadFlags, wg *sync.WaitGroup) error { +func addTorrents( + ctx context.Context, + client *torrent.Client, + flags downloadFlags, + wg *sync.WaitGroup, + fatalErr func(err error), +) error { testPeers := resolveTestPeers(flags.TestPeer) for _, arg := range flags.Torrent { t, err := func() (*torrent.Torrent, error) { @@ -133,6 +139,10 @@ func addTorrents(ctx context.Context, client *torrent.Client, flags downloadFlag if err != nil { return fmt.Errorf("adding torrent for %q: %w", arg, err) } + t.SetOnWriteChunkError(func(err error) { + err = fmt.Errorf("error writing chunk for %v: %w", t, err) + fatalErr(err) + }) if flags.Progress { torrentBar(t, flags.PieceStates) } @@ -344,17 +354,33 @@ func downloadErr(flags downloadFlags) error { client.WriteStatus(w) }) var wg sync.WaitGroup - err = addTorrents(ctx, client, flags, &wg) + fatalErr := make(chan error, 1) + err = addTorrents(ctx, client, flags, &wg, + func(err error) { + select { + case fatalErr <- err: + default: + panic(err) + } + }) if err != nil { return fmt.Errorf("adding torrents: %w", err) } started := time.Now() defer outputStats(client, flags) - wg.Wait() - if ctx.Err() == nil { - log.Print("downloaded ALL the torrents") - } else { - err = ctx.Err() + wgWaited := make(chan struct{}) + go func() { + defer close(wgWaited) + wg.Wait() + }() + select { + case <-wgWaited: + if ctx.Err() == nil { + log.Print("downloaded ALL the torrents") + } else { + err = ctx.Err() + } + case err = <-fatalErr: } clientConnStats := client.ConnStats() log.Printf(