jeessy2/ddns-go · error

请求 dnsla 失败: %w

Error message

请求 dnsla 失败: %w

What it means

After building the dnsla request, request() sends it with the package httpClient. Any transport-level failure (DNS resolution, TCP connect, TLS handshake, timeout, context cancellation) is wrapped as 请求 dnsla 失败 with the underlying error via %w. It means the HTTP exchange never completed, not that dnsla returned a bad status.

Source

Thrown at dns/dnsla.go:230

func (dnsla *Dnsla) request(method, apiAddr string, values []byte) (body []byte, err error) {
	req, err := http.NewRequest(
		method,
		apiAddr,
		bytes.NewReader(values),
	)
	if err != nil {
		return nil, fmt.Errorf("创建 dnsla 请求失败: %w", err)
	}
	// 设置自定义 Headers
	byteBuff := []byte(dnsla.DNS.ID + ":" + dnsla.DNS.Secret)
	token := "Basic " + base64.StdEncoding.EncodeToString(byteBuff)
	req.Header.Set("Authorization", token)
	req.Header.Set("Content-Type", "application/json;charset=utf-8")
	// 4. 发送请求
	client := dnsla.httpClient
	resp, err := client.Do(req)
	if err != nil {
		return nil, fmt.Errorf("请求 dnsla 失败: %w", err)
	}
	defer resp.Body.Close()

	body, err = io.ReadAll(resp.Body)
	if err != nil {
		return nil, fmt.Errorf("读取 dnsla 响应失败: %w", err)
	}
	if resp.StatusCode != http.StatusOK {
		return nil, fmt.Errorf("dnsla 请求失败,状态码: %d, 响应: %s", resp.StatusCode, string(body))
	}
	return body, nil
}

// 获得域名记录列表
func (dnsla *Dnsla) getRecordList(domain *config.Domain, typ string) (result []byte, err error) {
	recordTypeInt := "1"
	if typ == "AAAA" {
		recordTypeInt = "28"

View on GitHub (pinned to 5874c2e666)

Solutions

  1. Inspect the wrapped %w error to distinguish DNS vs connect vs TLS vs timeout
  2. Test reachability: curl -v https://<apiAddr> from the host running the app
  3. Check DNS/hosts, firewall rules, and proxy settings (HTTP_PROXY/HTTPS_PROXY) on the host
  4. Retry with backoff for transient network failures; increase httpClient.Timeout if requests are slow

Example fix

// before
resp, err := client.Do(req)
if err != nil {
  return nil, fmt.Errorf("请求 dnsla 失败: %w", err)
}
// after
resp, err := client.Do(req)
if err != nil {
  var netErr net.Error
  if errors.As(err, &netErr) && netErr.Timeout() {
    return nil, fmt.Errorf("请求 dnsla 超时: %w", err)
  }
  return nil, fmt.Errorf("请求 dnsla 失败: %w", err)
}
Defensive patterns

Strategy: retry

Validate before calling

// pre-flight connectivity check
conn, err := net.DialTimeout("tcp", host+":443", 3*time.Second)
if err != nil {
  return fmt.Errorf("无法连接 dnsla API 主机 %s: %w", host, err)
}
conn.Close()

Type guard

func isTimeoutErr(err error) bool {
  var ne net.Error
  return errors.As(err, &ne) && ne.Timeout()
}

Try / catch

resp, err := client.Do(req)
if err != nil {
  var ne net.Error
  if errors.As(err, &ne) && ne.Timeout() {
    return nil, fmt.Errorf("请求 dnsla 超时: %w", err)
  }
  return nil, fmt.Errorf("请求 dnsla 失败: %w", err) // retry transient failures with backoff
}

Prevention

When it happens

Trigger: create/modify -> request -> client.Do fails: dnsla API host unreachable, DNS failure, network outage, TLS certificate problem, or configured client timeout exceeded.

Common situations: No internet or firewall blocking the API host; dnsla API domain changed or is blocked in your region; proxy required but not configured; slow network triggering httpClient.Timeout; system clock skew breaking TLS.

Understand the failure class

Background: 'Something went wrong' / 'Request failed (500)' / 'HTTP error! status: 404' — what failed HTTP requests actually mean and how to find the real cause — this error's family across 28 libraries.

Related errors


AI-assisted analysis of jeessy2/ddns-go@5874c2e666 (2026-09-03). Data as JSON: /api/errors/5536828cd720baad. Report an issue: GitHub.