jd-opensource/joyagent-jdgenie · error · RuntimeException

调用接口" + url + "失败:" + response.message()

Error message

调用接口" + url + "失败:" + response.message()

What it means

OkHttpUtil.postJsonBody performs an HTTP POST and wraps any non-successful response into an unchecked RuntimeException that embeds the target URL and the HTTP status reason phrase. It is a generic transport-level failure signal, not a typed HTTP exception.

Solutions

  1. Log the full response body and status code (response.code(), not just message()) to identify the real cause.
  2. Check target service health/auth and correct the URL or credentials.
  3. Add retry with backoff for transient 5xx/429, and prefer a typed exception carrying the status code.

Example fix

// before
if (!response.isSuccessful()) {
    throw new RuntimeException("调用接口" + url + "失败:" + response.message());
}
// after
if (!response.isSuccessful()) {
    throw new IOException("调用接口" + url + "失败: HTTP " + response.code()
        + " " + response.message() + " body=" + peekBody(response));
}
Defensive patterns

Strategy: try-catch

Validate before calling

// pre-flight reachability check
HttpResponseProbe.probe(url, headers, 3); // ensure endpoint is reachable/authenticated before POST

Try / catch

try {
    return OkHttpUtil.postJsonBody(url, headers, jsonBody);
} catch (RuntimeException e) {
    if (e.getMessage() != null && e.getMessage().startsWith("调用接口")) {
        // parse URL from message, log, retry with backoff or failover
    } else throw e;
}

Prevention

When it happens

Trigger: Any postJsonBody call where the server returns a non-2xx response (4xx client error, 5xx server error, proxy rejection) — postNew returns a Response whose isSuccessful() is false.

Common situations: Downstream service returns 500 during an outage; auth token expired yielding 401; wrong URL path giving 404; gateway rate-limiting with 429.

Understand the failure class

Background: "API error: {status}" and "HTTP 401/403/404/429/5xx" errors: non-2xx HTTP responses explained — this error's family across 27 libraries.

Related errors


AI-assisted analysis of jd-opensource/joyagent-jdgenie@2417e0b8b6 (2026-09-08). Data as JSON: /api/errors/b191888a521d40ca. Report an issue: GitHub.

Appendix: source

Thrown at genie-backend/src/main/java/com/jd/genie/agent/util/OkHttpUtil.java:88

                .build();
    }

    public static Response postNew(String url, Map<String, String> header, String jsonBody) throws IOException {
        OkHttpClient httpClient = getOkHttpClient();
        RequestBody body = RequestBody.create(jsonBody, JSON);
        Request.Builder builder = new Request.Builder().url(url).post(body);
        if (!Objects.isNull(header)) {
            header.forEach(builder::addHeader);
        }

        return httpClient.newCall(builder.build()).execute();
    }

    public static String postJsonBody(String url, Map<String, String> headers, String jsonBody) throws IOException {
        log.info("post调用接口{}参数:{},{}", url, jsonBody, headers);
        try (Response response = postNew(url, headers, jsonBody)) {
            if (!response.isSuccessful()) {
                throw new RuntimeException("调用接口" + url + "失败:" + response.message());
            }
            return Objects.requireNonNull(response.body()).string();
        }
    }

    /**
     * 发送 POST 请求,以 JSON 格式传递参数
     *
     * @param url        请求的 URL
     * @param jsonParams JSON 格式的参数
     * @return 请求结果
     * @throws IOException 网络请求异常
     */
    public static String postJson(String url, String jsonParams, Map<String, String> headers, Long timeout) throws IOException {
        OkHttpClient client = createClient(timeout, timeout, timeout);
        RequestBody body = RequestBody.create(jsonParams, JSON);
        Request.Builder requestBuilder = new Request.Builder()
                .url(url)

View on GitHub (pinned to 2417e0b8b6)