From 302b3a11b1ede6c73add5da1e1e5a5b80ec6798a Mon Sep 17 00:00:00 2001 From: beardthelion <56458543+beardthelion@users.noreply.github.com> Date: Mon, 3 Aug 2026 12:35:45 -0500 Subject: [PATCH] fix(drivers): stop the upload retry loop when the context is canceled The 115 and pikpak multipart uploaders checked for cancellation with a `case <-ctx.Done()` inside a select, and a break there only leaves the select, not the enclosing `for retry := 0; retry < 3; retry++` loop. Cancelling an upload therefore ran all three attempts for every remaining chunk, each allocating a chunk-sized buffer and reading it off disk before firing a request that could not succeed, and reported a transport error instead of the cancellation. Move the check ahead of the select and use utils.IsCanceled, matching the pattern the other drivers already use. Assigning ctx.Err() to err is load-bearing: without it a cancelled chunk takes the success branch, counts toward progress, and appends a zero-value UploadPart. Found with staticcheck (SA4011). --- drivers/115/util.go | 6 ++++-- drivers/pikpak/util.go | 6 ++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/drivers/115/util.go b/drivers/115/util.go index 57c987349..104ebe8ec 100644 --- a/drivers/115/util.go +++ b/drivers/115/util.go @@ -337,9 +337,11 @@ func (d *Pan115) UploadByMultipart(ctx context.Context, params *driver115.Upload for chunk := range chunksCh { var part oss.UploadPart // 出现错误就继续尝试,共尝试3次 for retry := 0; retry < 3; retry++ { - select { - case <-ctx.Done(): + if utils.IsCanceled(ctx) { + err = ctx.Err() break + } + select { case <-ticker.C: if ossToken, err = d.client.GetOSSToken(); err != nil { // 到时重新获取ossToken errCh <- errors.Wrap(err, "刷新token时出现错误") diff --git a/drivers/pikpak/util.go b/drivers/pikpak/util.go index 1d091217a..b75bc2016 100644 --- a/drivers/pikpak/util.go +++ b/drivers/pikpak/util.go @@ -503,9 +503,11 @@ func (d *PikPak) UploadByMultipart(ctx context.Context, params *S3Params, fileSi for chunk := range chunksCh { var part oss.UploadPart // 出现错误就继续尝试,共尝试3次 for retry := 0; retry < 3; retry++ { - select { - case <-ctx.Done(): + if utils.IsCanceled(ctx) { + err = ctx.Err() break + } + select { case <-ticker.C: errCh <- errors.Wrap(err, "ossToken 过期") default: