{"record":{"id":"980d4149a787561a","repo":"jeessy2/ddns-go","slug":"dnsla-w-980d41","errorCode":null,"errorMessage":"读取 dnsla 响应失败: %w","messagePattern":"读取 dnsla 响应失败: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"dns/dnsla.go","lineNumber":236,"sourceCode":"\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"创建 dnsla 请求失败: %w\", err)\n\t}\n\t// 设置自定义 Headers\n\tbyteBuff := []byte(dnsla.DNS.ID + \":\" + dnsla.DNS.Secret)\n\ttoken := \"Basic \" + base64.StdEncoding.EncodeToString(byteBuff)\n\treq.Header.Set(\"Authorization\", token)\n\treq.Header.Set(\"Content-Type\", \"application/json;charset=utf-8\")\n\t// 4. 发送请求\n\tclient := dnsla.httpClient\n\tresp, err := client.Do(req)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"请求 dnsla 失败: %w\", err)\n\t}\n\tdefer resp.Body.Close()\n\n\tbody, err = io.ReadAll(resp.Body)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"读取 dnsla 响应失败: %w\", err)\n\t}\n\tif resp.StatusCode != http.StatusOK {\n\t\treturn nil, fmt.Errorf(\"dnsla 请求失败，状态码: %d, 响应: %s\", resp.StatusCode, string(body))\n\t}\n\treturn body, nil\n}\n\n// 获得域名记录列表\nfunc (dnsla *Dnsla) getRecordList(domain *config.Domain, typ string) (result []byte, err error) {\n\trecordTypeInt := \"1\"\n\tif typ == \"AAAA\" {\n\t\trecordTypeInt = \"28\"\n\t}\n\tparams := domain.GetCustomParams()\n\tparams.Set(\"domain\", domain.DomainName)\n\tparams.Set(\"host\", domain.GetSubDomain())\n\tparams.Set(\"type\", recordTypeInt)\n\tparams.Set(\"pageIndex\", \"1\")","sourceCodeStart":218,"sourceCodeEnd":254,"githubUrl":"https://github.com/jeessy2/ddns-go/blob/5874c2e6667c69357ab95079421131104bd3fcae/dns/dnsla.go#L218-L254","documentation":"After a successful HTTP exchange, request() reads the entire dnsla response body with io.ReadAll. If reading the body fails, it returns 读取 dnsla 响应失败 wrapping the cause. This indicates the connection dropped or was reset mid-response, or the response body stream errored.","triggerScenarios":"client.Do succeeded but io.ReadAll(resp.Body) fails: server closed the connection prematurely, network interruption during body transfer, timeout while reading a large body, or gzip/compression errors.","commonSituations":"Unstable network or mobile connection dropping mid-transfer; dnsla server-side errors truncating responses; proxy/CDN cutting long responses; very low client timeout interrupting body read.","solutions":["Check the wrapped %w error for 'unexpected EOF'/'connection reset' vs timeout","Retry the request — transient body read failures usually succeed on retry","Increase httpClient.Timeout or use a context with a generous deadline for large responses","Verify no intermediate proxy is truncating responses; test with curl to compare","Use errors.Is/As on the wrapped cause to implement targeted retry logic"],"exampleFix":"// before\nbody, err = io.ReadAll(resp.Body)\nif err != nil {\n  return nil, fmt.Errorf(\"读取 dnsla 响应失败: %w\", err)\n}\n// after\nbody, err = io.ReadAll(resp.Body)\nif err != nil {\n  if isRetryable(err) { // e.g. io.ErrUnexpectedEOF, ECONNRESET\n    return dnsla.request(method, apiAddr, values) // simple retry\n  }\n  return nil, fmt.Errorf(\"读取 dnsla 响应失败: %w\", err)\n}","handlingStrategy":"retry","validationCode":"// nothing to check before the call; guard the read instead\nlr := io.LimitReader(resp.Body, 1<<20) // cap size to avoid huge reads\nbody, err := io.ReadAll(lr)","typeGuard":"func isBodyReadErr(err error) bool {\n  return errors.Is(err, io.ErrUnexpectedEOF) || errors.Is(err, syscall.ECONNRESET)\n}","tryCatchPattern":"body, err = io.ReadAll(resp.Body)\nif err != nil {\n  if isBodyReadErr(err) {\n    return nil, retryable(fmt.Errorf(\"读取 dnsla 响应失败: %w\", err))\n  }\n  return nil, fmt.Errorf(\"读取 dnsla 响应失败: %w\", err)\n}","preventionTips":["Retry idempotent requests on transient body-read failures","Set realistic timeouts so large responses aren't cut off mid-read","Avoid proxies that buffer/truncate; test with curl to isolate intermediaries","Check server health if truncation happens repeatedly"],"tags":["go","network","http","io"],"backgroundTag":"response-body-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"}