{"record":{"id":"c7d5f2886da98389","repo":"chenhg5/cc-connect","slug":"read-response-w-c7d5f2","errorCode":null,"errorMessage":"read response: %w","messagePattern":"read response: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"platform/dingtalk/dingtalk.go","lineNumber":662,"sourceCode":"\tdownloadURL, err := p.getDownloadURL(downloadCode)\n\tif err != nil {\n\t\treturn nil, \"\", fmt.Errorf(\"get download URL: %w\", err)\n\t}\n\n\t// Download audio file\n\tresp, err := p.httpClient.Get(downloadURL)\n\tif err != nil {\n\t\treturn nil, \"\", fmt.Errorf(\"http get: %w\", err)\n\t}\n\tdefer func() { _ = resp.Body.Close() }()\n\n\tif resp.StatusCode != http.StatusOK {\n\t\treturn nil, \"\", fmt.Errorf(\"download returned status %d\", resp.StatusCode)\n\t}\n\n\tdata, err := io.ReadAll(resp.Body)\n\tif err != nil {\n\t\treturn nil, \"\", fmt.Errorf(\"read response: %w\", err)\n\t}\n\n\t// Determine MIME type from Content-Type header\n\tmimeType := resp.Header.Get(\"Content-Type\")\n\tif mimeType == \"\" {\n\t\tmimeType = \"audio/amr\" // Default to AMR if not specified\n\t}\n\n\treturn data, mimeType, nil\n}\n\nfunc (p *Platform) getDownloadURL(downloadCode string) (string, error) {\n\ttoken, err := p.getAccessToken()\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"get access token: %w\", err)\n\t}\n\n\treqBody := map[string]string{","sourceCodeStart":644,"sourceCodeEnd":680,"githubUrl":"https://github.com/chenhg5/cc-connect/blob/4000b2338aa6e850c99df54f8b0ed6ed7460b401/platform/dingtalk/dingtalk.go#L644-L680","documentation":"downloadAudio fetched the DingTalk audio file from its download URL but io.ReadAll on the response body failed — connection reset or timeout mid-download. Wraps the read error and aborts audio message handling.","triggerScenarios":"io.ReadAll(resp.Body) in downloadAudio errored while draining the body of the audio download response.","commonSituations":"Flaky network or CDN closing the connection mid-transfer; HTTP client timeout cutting off a large audio file; proxy killing long-lived connections.","solutions":["Retry the download (fetch a fresh URL if needed) — this is usually transient.","Increase the httpClient timeout if audio files are large.","Check network stability/proxy idle-timeout settings on the host.","Log the wrapped cause to confirm whether it's 'unexpected EOF' vs 'context deadline exceeded' and treat accordingly."],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"if err != nil {\n    if errors.Is(err, io.ErrUnexpectedEOF) || errors.Is(err, context.DeadlineExceeded) {\n        return retryDownload(1) // transient; fetch fresh URL and retry\n    }\n    return fmt.Errorf(\"audio read: %w\", err)\n}","preventionTips":["Use an httpClient with an adequate timeout for the expected audio sizes","Prefer downloading on stable networks; avoid reusing connections through aggressive proxies","Log whether the failure is EOF vs deadline to pick retry vs alert"],"tags":["dingtalk","audio","io","network"],"backgroundTag":"http-request-failed","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"}