{"record":{"id":"e264f8925fabd0cc","repo":"chenhg5/cc-connect","slug":"range-chunk-retries-exhausted-w","errorCode":null,"errorMessage":"range chunk retries exhausted: %w","messagePattern":"range chunk retries exhausted: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"platform/feishu/resource_download.go","lineNumber":381,"sourceCode":"\t\tif resp.StatusCode >= 500 && resp.StatusCode < 600 && attempt < maxTransientRetries {\n\t\t\tlastErr = fmt.Errorf(\"range status %d body=%q\", resp.StatusCode, strings.TrimSpace(string(body)))\n\t\t\tcontinue\n\t\t}\n\n\t\tif resp.StatusCode >= 200 && resp.StatusCode < 300 && end-start+1 == int64(len(body)) {\n\t\t\t// Server ignored Range and returned a 200 with exactly the bytes\n\t\t\t// we wanted — fine for the last chunk of a file, slightly off for\n\t\t\t// non-tail chunks. Caller decides; we return what we got.\n\t\t\treturn body, nil\n\t\t}\n\n\t\treturn nil, fmt.Errorf(\"range request status=%d body=%q\", resp.StatusCode, strings.TrimSpace(string(body)))\n\t}\n\n\tif lastErr == nil {\n\t\tlastErr = errors.New(\"range chunk retries exhausted\")\n\t}\n\treturn nil, fmt.Errorf(\"range chunk retries exhausted: %w\", lastErr)\n}\n\n// defaultResourceChunkSize returns the chunk size used when a Platform is\n// constructed without going through newPlatform (tests, manual fixtures).\n// Matches the production default of 8 MiB.\nfunc defaultResourceChunkSize() int64 { return 8 * 1024 * 1024 }\n\n// fetchResourceTokenOrDefault returns the bearer token used for resource\n// downloads. Tests can inject a stub via Platform.fetchResourceToken;\n// production callers fall through to fetchFreshTenantAccessToken which uses\n// the lark SDK to mint a fresh tenant token on demand.\nfunc (p *Platform) fetchResourceTokenOrDefault(ctx context.Context) (string, error) {\n\tif p.fetchResourceToken != nil {\n\t\treturn p.fetchResourceToken(ctx)\n\t}\n\treturn p.fetchFreshTenantAccessToken(ctx)\n}\n","sourceCodeStart":363,"sourceCodeEnd":399,"githubUrl":"https://github.com/chenhg5/cc-connect/blob/4000b2338aa6e850c99df54f8b0ed6ed7460b401/platform/feishu/resource_download.go#L363-L399","documentation":"resourceRangeChunk retries a chunk only up to maxTransientRetries times for transient errors (network hiccups, 5xx). When all attempts fail, it returns 'range chunk retries exhausted' wrapping the last observed error (or a generic message if none was recorded). This signals sustained failure of one range fetch, not a single blip.","triggerScenarios":"resourceFetchRemainingChunks -> resourceRangeChunk: every attempt in the retry loop fails — repeated transient io errors or repeated 5xx responses — until attempt >= maxTransientRetries, then this wrapped error is returned.","commonSituations":"Prolonged network outage; Feishu API brownout during a large download; aggressive proxy dropping Range requests; host DNS/resolution issues persisting across retries.","solutions":["Wait and retry the download after the transient condition clears (the wrapped lastErr tells you what kept failing)","Check network connectivity/proxy stability and Feishu service health","Increase maxTransientRetries and/or add backoff between attempts for flaky networks","Split the file into smaller chunks so transient outages cost less progress"],"exampleFix":"// before\ngo download(fileToken)\n// after: retry whole download with backoff\nfor i := 0; i < 3; i++ {\n    err := download(fileToken)\n    if err == nil || !strings.Contains(err.Error(), \"retries exhausted\") { break }\n    time.Sleep(time.Duration(1<<i) * time.Second)\n}","handlingStrategy":"retry","validationCode":"// pre-flight reachability check before chunked downloads\nif err := pingFeishuAPI(3*time.Second); err != nil {\n    return fmt.Errorf(\"skip download, API unreachable: %w\", err)\n}","typeGuard":null,"tryCatchPattern":"if err := downloadResource(fileToken); err != nil && strings.Contains(err.Error(), \"retries exhausted\") {\n    // sustained failure: exponential backoff, then alert\n    backoffRetry(func() error { return downloadResource(fileToken) }, 5)\n}","preventionTips":["Set maxTransientRetries and backoff appropriate to your network reliability","Monitor network health; alert on repeated exhausted-retry errors","Avoid downloads during known maintenance windows","Use alerting on the wrapped lastErr to distinguish 5xx vs network causes"],"tags":["retry","network","download","feishu"],"backgroundTag":"request-timeout","analyzedSha":"4000b2338aa6e850c99df54f8b0ed6ed7460b401","analyzedAt":"2026-09-06T11:45:09.575Z","contentChangedAt":"2026-09-06T11:45:09.575Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}