flipped-aurora/gin-vue-admin · error
function bucketManager.Batch() failed, err:
Error message
function bucketManager.Batch() failed, err:
What it means
Wraps a fatal error from Qiniu's bucketManager.Batch() in DeleteFiles(). Batch deletes objects in bulk; the code only treats it as fatal when the batch result slice is empty (no per-key results at all).
Source
Thrown at server/utils/upload/qiniu.go:112
// DeleteFiles 批量删除对象,通过通用 Batch 接口,逐项检查 code(200/204 成功)。
func (*Qiniu) DeleteFiles(ctx context.Context, keys []string) ([]DeleteFailure, error) {
if len(keys) == 0 {
return nil, nil
}
bucket := global.GVA_CONFIG.Qiniu.Bucket
operations := make([]string, 0, len(keys))
for _, key := range keys {
operations = append(operations, storage.URIDelete(bucket, key))
}
bucketManager := newBucketManager()
ret, err := bucketManager.Batch(operations)
if err != nil {
// 部分 key 失败时 Batch 仍可能返回结果,这里仅当完全没有结果时视为致命错误。
if len(ret) == 0 {
logger.WithCtx(ctx).Mod("upload").Err(err).Error("function bucketManager.Batch() failed")
return nil, errors.New("function bucketManager.Batch() failed, err:" + err.Error())
}
logger.WithCtx(ctx).Mod("upload").Err(err).Error("function bucketManager.Batch() partial failure")
}
failed := make([]DeleteFailure, 0)
for i, op := range ret {
// 200 / 204 视为删除成功
if op.Code != http.StatusOK && op.Code != http.StatusNoContent {
var key string
if i < len(keys) {
key = keys[i]
}
failed = append(failed, DeleteFailure{Key: key, Err: fmt.Errorf("delete failed, code: %d", op.Code)})
}
}
return failed, nil
}
View on GitHub (pinned to 3136500ef3)
Solutions
- Inspect the wrapped err suffix for the underlying Qiniu error code
- Reduce batch size (split keys into smaller chunks, e.g. <=1000 per Batch)
- Re-check Qiniu AK/SK and bucket configuration
- Retry on transient network errors; per-key failures are returned via DeleteFailure, not this error
Example fix
// before
uploadQiniu.DeleteFiles(ctx, thousandsOfKeys) // one huge Batch may fail fatally
// after
for chunk := range slices.Chunk(keys, 500) {
uploadQiniu.DeleteFiles(ctx, chunk)
} Defensive patterns
Strategy: retry
Validate before calling
if len(keys) > 1000 {
return fmt.Errorf("batch too large: %d keys", len(keys))
} Try / catch
failed, err := q.DeleteFiles(ctx, keys)
if err != nil {
if isTransient(err) {
// retry with backoff
}
return err
}
// handle partial failures in `failed` slice separately Prevention
- Chunk key lists to a sane batch size
- Check per-key DeleteFailure results instead of assuming all-or-nothing
- Keep Qiniu credentials valid and rotate before expiry
When it happens
Trigger: Calling DeleteFiles(ctx, keys) when the Batch call fails entirely: auth failure, invalid bucket, oversized batch, or network error, with len(ret)==0.
Common situations: Expired/incorrect Qiniu credentials, batch containing too many keys for one request, bucket region mismatch, transient network outage.
Related errors
- function formUploader.Put() failed, err:
- function bucketManager.Stat() failed, err:
- function bucketManager.ListFiles() failed, err:
- 上传文件到minio失败, err:
- function file.Open() failed, err:
AI-assisted analysis of flipped-aurora/gin-vue-admin@3136500ef3 (2026-08-31).
Data as JSON: /api/errors/ad8c1e9749c38e36.
Report an issue: GitHub.