jeessy2/ddns-go · error

Rainyun API error, code=

Error message

Rainyun API error, code=%d

What it means

dns/rainyun.go fallback error: when the Rainyun API returns code != 200 but the response Message field is empty, request() (used by getRecordList, createRecord, patchRecord) reports "Rainyun API error, code=%d" with the numeric code only. It exists so callers never get an empty error string.

Solutions

  1. Look up the numeric code in the Rainyun API documentation
  2. Retry if the code is in the 5xx range; it may be transient
  3. Check Rainyun status page or console for ongoing incidents
  4. Update the library/provider SDK if the API response format changed

Example fix

// before
return fmt.Errorf("Rainyun API error, code=%d", apiResp.Code)
// after (caller: retry on transient codes)
if strings.Contains(err.Error(), "code=5") {
	time.Sleep(2 * time.Second)
	return provider.getRecordList(domain) // retry once
}
Defensive patterns

Strategy: retry

Validate before calling

// preflight: ensure API reachable and key set
if apiKey == "" { return errors.New("rainyun: missing API key") }

Type guard

// detect the code-only fallback error
func isCodeOnlyErr(err error) (code int, ok bool) {
	_, e := fmt.Sscanf(errString(err), "Rainyun API error, code=%d", &code)
	return code, e == nil
}

Try / catch

if err != nil {
	if code, ok := isCodeOnlyErr(err); ok && code >= 500 {
		time.Sleep(2 * time.Second)
		return retryOnce()
	}
	return err
}

Prevention

When it happens

Trigger: Any Rainyun API call whose JSON body has code != 200 and an empty Message — typically provider-side failures that omit a human-readable message (5xx-style conditions, unknown codes, malformed provider responses).

Common situations: Rainyun backend incidents returning error codes without messages; API version changes that alter the response envelope; proxy middleware stripping the JSON body.

Related errors


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

Appendix: source

Thrown at dns/rainyun.go:260

	if method == http.MethodPost || method == http.MethodPatch || method == http.MethodPut {
		req.Header.Set("Content-Type", "application/json")
	}

	resp, err := rainyun.httpClient.Do(req)
	if err != nil {
		return err
	}

	var apiResp RainyunResp
	err = util.GetHTTPResponse(resp, err, &apiResp)
	if err != nil {
		return err
	}
	if apiResp.Code != 200 {
		if apiResp.Message != "" {
			return fmt.Errorf("%s", apiResp.Message)
		}
		return fmt.Errorf("Rainyun API error, code=%d", apiResp.Code)
	}

	if result == nil {
		return nil
	}

	dataBytes, err := json.Marshal(apiResp.Data)
	if err != nil {
		return err
	}
	return json.Unmarshal(dataBytes, result)
}

View on GitHub (pinned to 5874c2e666)