cmd/torrent/download.go | 40 +++++++++++++++++++++++++++++++++------- diff --git a/cmd/torrent/download.go b/cmd/torrent/download.go index 065ea2ad02e37ca7bd86a1c4c5ba2d020ee627e8..1fc4759f99f357cf9f5df69de14624bc9aa92bac 100644 --- a/cmd/torrent/download.go +++ b/cmd/torrent/download.go @@ -89,7 +89,13 @@ } 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 @@ }() 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 @@ http.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) { 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(