{"record":{"id":"21067b0869a6ed61","repo":"flipped-aurora/gin-vue-admin","slug":"function-bucketmanager-listfiles-failed-err","errorCode":null,"errorMessage":"function bucketManager.ListFiles() failed, err:","messagePattern":"function bucketManager\\.ListFiles\\(\\) failed, err:","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/utils/upload/qiniu.go","lineNumber":141,"sourceCode":"\t\t\t\tkey = keys[i]\n\t\t\t}\n\t\t\tfailed = append(failed, DeleteFailure{Key: key, Err: fmt.Errorf(\"delete failed, code: %d\", op.Code)})\n\t\t}\n\t}\n\treturn failed, nil\n}\n\n// ListFiles 按前缀列举对象，cursor 映射为七牛的 marker。\nfunc (*Qiniu) ListFiles(ctx context.Context, prefix, cursor string, limit int) ([]FileInfo, string, bool, error) {\n\tif limit <= 0 {\n\t\tlimit = 100\n\t}\n\n\tbucketManager := newBucketManager()\n\tentries, _, nextMarker, hasNext, err := bucketManager.ListFiles(global.GVA_CONFIG.Qiniu.Bucket, prefix, \"\", cursor, limit)\n\tif err != nil {\n\t\tlogger.WithCtx(ctx).Mod(\"upload\").Err(err).Error(\"function bucketManager.ListFiles() failed\")\n\t\treturn nil, \"\", false, errors.New(\"function bucketManager.ListFiles() failed, err:\" + err.Error())\n\t}\n\n\tfiles := make([]FileInfo, 0, len(entries))\n\tfor _, entry := range entries {\n\t\t// PutTime 单位为 100 纳秒，除以 1e7 得到秒级 Unix 时间戳\n\t\tfiles = append(files, FileInfo{\n\t\t\tKey:          entry.Key,\n\t\t\tSize:         entry.Fsize,\n\t\t\tLastModified: time.Unix(0, entry.PutTime*100),\n\t\t\tContentType:  entry.MimeType,\n\t\t})\n\t}\n\n\tnextCursor := \"\"\n\tif hasNext {\n\t\tnextCursor = nextMarker\n\t}\n\treturn files, nextCursor, hasNext, nil","sourceCodeStart":123,"sourceCodeEnd":159,"githubUrl":"https://github.com/flipped-aurora/gin-vue-admin/blob/3136500ef380842b0eb6c4daa87c3f8a47fcf9e0/server/utils/upload/qiniu.go#L123-L159","documentation":"Wraps an error from Qiniu's bucketManager.ListFiles() in ListFiles(). ListFiles enumerates bucket objects with prefix/marker pagination; any SDK-level failure (auth, network, bad cursor) produces this error.","triggerScenarios":"Calling ListFiles(ctx, prefix, cursor, limit) when the Qiniu list API fails: invalid marker/cursor from a stale page, auth error, or network failure.","commonSituations":"Passing an expired or malformed nextMarker as cursor, wrong bucket config, region endpoint unreachable, SDK credentials revoked.","solutions":["Check the wrapped err suffix for the real Qiniu error (401/403/network)","Verify bucket name and credentials in GVA_CONFIG.Qiniu","Restart listing from an empty cursor if a stale marker is rejected","Confirm network connectivity to the bucket's region endpoint"],"exampleFix":"// before\nfiles, marker, hasMore, err := q.ListFiles(ctx, \"\", staleMarker, 10)\n// after\nif err != nil && strings.Contains(err.Error(), \"marker\") {\n    files, marker, hasMore, err = q.ListFiles(ctx, \"\", \"\", 10) // restart pagination\n}","handlingStrategy":"try-catch","validationCode":"if cursor != \"\" && !isValidMarker(cursor) {\n    cursor = \"\" // restart from beginning\n}","typeGuard":null,"tryCatchPattern":"files, marker, hasMore, err := q.ListFiles(ctx, prefix, cursor, limit)\nif err != nil {\n    // inspect wrapped error; reset cursor and retry once\n    return nil, \"\", false, fmt.Errorf(\"list objects failed: %w\", err)\n}","preventionTips":["Always feed back the exact nextMarker returned by the previous page","Validate bucket/credentials at startup","Handle pagination restarts for stale markers"],"tags":["qiniu","upload","list-objects","object-storage"],"backgroundTag":"object-storage-list-failed","analyzedSha":"3136500ef380842b0eb6c4daa87c3f8a47fcf9e0","analyzedAt":"2026-08-31T13:50:02.721Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}