{"record":{"id":"8306d0ab4c295239","repo":"jeessy2/ddns-go","slug":"v-8306d0","errorCode":null,"errorMessage":"生成签名失败: %v","messagePattern":"生成签名失败: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"dns/tnethk.go","lineNumber":252,"sourceCode":"\n\t// 6. 重新构造最终的查询字符串(包含签名)\n\tkeys = append(keys, \"Signature\")\n\tsort.Strings(keys)\n\tvar finalQuery []string\n\tfor _, k := range keys {\n\t\tencodedKey := util.PercentEncode(k)\n\t\tencodedValue := util.PercentEncode(params[k])\n\t\tfinalQuery = append(finalQuery, encodedKey+\"=\"+encodedValue)\n\t}\n\n\treturn strings.Join(finalQuery, \"&\"), nil\n}\n\nfunc (t *Tnethk) request(apiPath string, params map[string]string, method string) ([]byte, error) {\n\t// 生成签名\n\tqueryString, err := t.sign(params, method)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"生成签名失败: %v\", err)\n\t}\n\n\t// 构造完整URL\n\tbaseURL := \"https://www.tnet.hk\"\n\tfullURL := baseURL + apiPath + \"?\" + queryString\n\n\t// 创建HTTP请求\n\treq, err := http.NewRequest(method, fullURL, nil)\n\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)","sourceCodeStart":234,"sourceCodeEnd":270,"githubUrl":"https://github.com/jeessy2/ddns-go/blob/5874c2e6667c69357ab95079421131104bd3fcae/dns/tnethk.go#L234-L270","documentation":"dns/tnethk.go request() wraps a failure of t.sign(params, method) with \"生成签名失败: %v\" (signature generation failed). Signing runs before every Tnet.hk API call (create, modify, getRecordList), so any error building the query-string signature aborts the request locally without network I/O.","triggerScenarios":"create, modify, or getRecordList calls where sign() fails — typically missing/empty API credentials or secret in the provider config causing HMAC/query construction to error.","commonSituations":"Unset or blank API key/secret in the DDNS config; misconfigured credential environment variables; secret containing characters that break query-string encoding; a provider API change requiring a new signature algorithm.","solutions":["Check that the Tnet.hk API key and secret are set in your configuration","Inspect the wrapped %v error to see the exact signing failure","Re-enter credentials avoiding stray whitespace/newlines","Update the library if Tnet.hk changed its signature scheme"],"exampleFix":"// before\nqueryString, err := t.sign(params, method)\nif err != nil {\n\treturn nil, fmt.Errorf(\"生成签名失败: %v\", err)\n}\n// after (caller: validate creds before calling)\nif provider.apiKey == \"\" || provider.secret == \"\" {\n\treturn fmt.Errorf(\"tnethk: api key/secret must be configured\")\n}","handlingStrategy":"validation","validationCode":"// before calling any tnethk operation\nif tnethkAPIKey == \"\" || tnethkSecret == \"\" {\n\treturn errors.New(\"tnethk: API key and secret must be configured\")\n}","typeGuard":null,"tryCatchPattern":"if err != nil && strings.Contains(err.Error(), \"生成签名失败\") {\n\treturn fmt.Errorf(\"tnethk signing failed — check credentials: %w\", err)\n}","preventionTips":["Validate key/secret are non-empty and trimmed at startup","Fail fast in config loading rather than at request time","Test signing with a dry-run before enabling automated DDNS"],"tags":["signature","auth","config"],"backgroundTag":"api-signature-generation-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"}