{"record":{"id":"23da9d7b18a59c13","repo":"jeessy2/ddns-go","slug":"v-23da9d","errorCode":null,"errorMessage":"读取响应失败: %v","messagePattern":"读取响应失败: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"dns/eranet.go","lineNumber":279,"sourceCode":"\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"创建请求失败: %v\", err)\n\t}\n\n\t// 设置请求头\n\treq.Header.Set(\"Accept\", \"application/json\")\n\n\t// 发送请求\n\tclient := t.httpClient\n\tresp, err := client.Do(req)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"请求失败: %v\", err)\n\t}\n\tdefer resp.Body.Close()\n\n\t// 读取响应\n\tbody, err := io.ReadAll(resp.Body)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"读取响应失败: %v\", err)\n\t}\n\n\t// 检查HTTP状态码\n\tif resp.StatusCode != http.StatusOK {\n\t\treturn nil, fmt.Errorf(\"API请求失败，状态码: %d, 响应: %s\", resp.StatusCode, string(body))\n\t}\n\n\treturn body, nil\n}\n","sourceCodeStart":261,"sourceCodeEnd":289,"githubUrl":"https://github.com/jeessy2/ddns-go/blob/5874c2e6667c69357ab95079421131104bd3fcae/dns/eranet.go#L261-L289","documentation":"Thrown by Eranet.request when io.ReadAll fails to read the response body from the eranet.com API after a successful HTTP round-trip. This is rare and usually indicates the connection dropped mid-response, the body stream errored, or something interfered with resp.Body.","triggerScenarios":"io.ReadAll(resp.Body) returns an error: server closed the connection before sending the full body, chunked transfer-encoding error, or the response context/timer expired while reading.","commonSituations":"Unstable network dropping large responses mid-transfer; eranet API server prematurely closing keep-alive connections; client timeouts that cut off body reads.","solutions":["Retry the request — the failure is usually transient","Increase the http.Client timeout if body reads are being cut off","Check whether a proxy or middlebox truncates responses","Verify the eranet API endpoint is healthy (compare with curl output)"],"exampleFix":"// before\nbody, err := io.ReadAll(resp.Body)\nif err != nil {\n    return nil, fmt.Errorf(\"读取响应失败: %v\", err)\n}\n// after\nbody, err := io.ReadAll(resp.Body)\nif err != nil {\n    return nil, fmt.Errorf(\"读取响应失败: %w\", err) // caller should retry\n}","handlingStrategy":"retry","validationCode":null,"typeGuard":"var netErr net.Error\nif errors.As(err, &netErr) && netErr.Timeout() {\n    // body read hit a timeout — safe to retry\n}","tryCatchPattern":"body, err := eranetClient.ModifyRecord(params)\nif err != nil {\n    if strings.Contains(err.Error(), \"读取响应失败\") {\n        return retryWithBackoff(3, func() error {\n            _, err = eranetClient.ModifyRecord(params)\n            return err\n        })\n    }\n    return err\n}","preventionTips":["Use a client timeout generous enough to read the full response","Avoid custom transports that wrap/shorten resp.Body","Disable aggressive keep-alive pruning if the API server closes connections early","Monitor for repeated occurrences — persistent truncation points to a middlebox"],"tags":["network","http","io","response-body"],"backgroundTag":"response-read-failed","analyzedSha":"5874c2e6667c69357ab95079421131104bd3fcae","analyzedAt":"2026-09-03T15:41:16.799Z","contentChangedAt":"2026-09-03T15:41:16.799Z","schemaVersion":2},"datasetVersion":"2026-09-11T00:17:11.886Z"}