{"record":{"id":"5d7a09d07500c9d5","repo":"jeessy2/ddns-go","slug":"api-d-s-5d7a09","errorCode":null,"errorMessage":"API请求失败，状态码: %d, 响应: %s","messagePattern":"API请求失败，状态码: (.+?), 响应: (.+?)","errorType":"http","errorClass":null,"httpStatus":null,"severity":"error","filePath":"dns/nowcn.go","lineNumber":273,"sourceCode":"\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":255,"sourceCodeEnd":278,"githubUrl":"https://github.com/jeessy2/ddns-go/blob/5874c2e6667c69357ab95079421131104bd3fcae/dns/nowcn.go#L255-L278","documentation":"dns/nowcn.go returns this when the Nowcn API answers with an HTTP status other than 200. The message embeds the status code and the raw response body, so it is a generic non-2xx API rejection inside the shared request() helper (create, modify, getRecordList).","triggerScenarios":"Any Nowcn API call that receives 401/403 (bad API credentials), 4xx (malformed parameters), or 5xx (server-side error) instead of HTTP 200.","commonSituations":"Expired or wrong API key/password in config; domain name not owned by the account; parameter formatting changes after provider API updates; Nowcn server outages returning 5xx.","solutions":["Read the embedded response body in the message — it usually names the exact API-side problem","Verify Nowcn API credentials (key/secret) in your configuration","Confirm the domain and record parameters match what the Nowcn dashboard shows","If status is 5xx, wait and retry; contact Nowcn support if persistent"],"exampleFix":"// before\nreturn nil, fmt.Errorf(\"API请求失败，状态码: %d, 响应: %s\", resp.StatusCode, string(body))\n// after (caller: branch on auth vs transient)\nvar nerr *fmt.Error // wrap or parse from message\nif strings.Contains(err.Error(), \"状态码: 401\") || strings.Contains(err.Error(), \"状态码: 403\") {\n\t// refresh credentials in config and re-run\n} else if strings.Contains(err.Error(), \"状态码: 5\") {\n\t// retry with backoff\n}","handlingStrategy":"type-guard","validationCode":"// validate credentials present before calling\nif apiKey == \"\" || apiPassword == \"\" {\n\treturn errors.New(\"nowcn: missing API credentials\")\n}","typeGuard":"// classify the wrapped status-code error\nfunc isNon200(err error) bool {\n\treturn err != nil && strings.Contains(err.Error(), \"API请求失败，状态码:\")\n}\nfunc statusFrom(err error) string {\n\ti := strings.Index(err.Error(), \"状态码: \")\n\tif i < 0 { return \"\" }\n\treturn err.Error()[i+len(\"状态码: \"):][:3]\n}","tryCatchPattern":"if err != nil {\n\tif isNon200(err) {\n\t\tswitch code := statusFrom(err); {\n\t\tcase code == \"401\" || code == \"403\":\n\t\t\tlog.Fatal(\"nowcn: bad credentials — fix config\")\n\t\tcase strings.HasPrefix(code, \"5\"):\n\t\t\t// transient: schedule retry\n\t\t}\n\t}\n}","preventionTips":["Rotate and verify Nowcn credentials on a schedule","Log the full error (it embeds the response body) for diagnosis","Alert on 5xx spikes rather than retrying indefinitely"],"tags":["http-status","api-error","auth"],"backgroundTag":"http-non-2xx-api-response","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"}