jd-opensource/joyagent-jdgenie · error · RuntimeException

返回结果为空!

Error message

返回结果为空!

What it means

httpReqThrowException executes an HTTP request and requires a non-empty response body via Objects.requireNonNull. When the entity string is null (no response body, or response/response.getEntity() is null) an NPE is caught and rethrown as RuntimeException("返回结果为空!", i.e. 'response is empty').

Solutions

  1. Check the HTTP status code and response entity for null before parsing
  2. Only call httpReqThrowException for endpoints that guarantee a body; use a tolerant variant otherwise
  3. Inspect the wrapped NPE cause (logged with the URL) to determine why the body was missing
  4. Fix the server/proxy to return a proper body or a non-2xx error instead of an empty 200
  5. Add retry logic for transient network failures

Example fix

// before
String body = httpUtils.httpReqThrowException(request);
// after
HttpResponse response = httpClient.execute(request);
if (response.getStatusLine().getStatusCode() == 204 || response.getEntity() == null) {
    return null; // or default value
}
String body = EntityUtils.toString(response.getEntity());
Defensive patterns

Strategy: try-catch

Validate before calling

HttpUriRequest req = ...;
// pre-check: only call httpReqThrowException on endpoints documented to return a body
HttpResponse probe = HttpClient.INS.getHttpClient().execute((HttpUriRequest) req);
int status = probe.getStatusLine().getStatusCode();
if (status == 204 || probe.getEntity() == null) { /* handle empty */ }

Try / catch

try {
    String body = httpUtils.httpReqThrowException(request);
} catch (RuntimeException e) {
    Throwable cause = e.getCause();
    if (cause instanceof NullPointerException) {
        // empty response body — use default/fallback
    } else {
        throw e;
    }
}

Prevention

When it happens

Trigger: The remote server returns 204 No Content, an empty body, or a null entity; connection failures producing a response without an entity; HttpClient returning a response whose entity was already consumed.

Common situations: Calling endpoints that legitimately return empty bodies; proxies/gateways stripping the body; server errors returning no payload; timeout or reset mid-response.

Related errors


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

Appendix: source

Thrown at genie-backend/src/main/java/com/jd/genie/util/HttpUtils.java:130

        httpReq.setConfig(requestConfig);
        // 传入header信息
        if (headers != null && !headers.isEmpty()) {
            for (Map.Entry<String, String> entry : headers.entrySet()) {
                httpReq.setHeader(entry.getKey(), String.valueOf(entry.getValue()));
            }
        }
        // 传入body信息
        if (StringUtils.isNotEmpty(body)) {
            ((HttpEntityEnclosingRequestBase) httpReq).setEntity(new StringEntity(body, ContentType.create("application/json", "utf-8")));
        }
        CloseableHttpResponse response = null;
        try {
            response = HttpClient.INS.getHttpClient().execute(httpReq);
            String responseEntityStr = EntityUtils.toString(response.getEntity());
            return Objects.requireNonNull(responseEntityStr);
        } catch (NullPointerException e) {
            log.error("httpReq请求失败:url:{}", url, e);
            throw new RuntimeException("返回结果为空!", e);
        } catch (Exception e) {
            log.error("httpReq请求失败:url:{}", url, e);
            throw new RuntimeException(e);
        } finally {
            close(response);
        }
    }

    private static HttpRequestBase getHttpRequest(String type, String url) {
        HttpRequestBase httpReq = null;
        switch (type) {
            case "post":
                httpReq = new HttpPost(url);
                break;
            case "put":
                httpReq = new HttpPut(url);
                break;
            case "delete":

View on GitHub (pinned to 2417e0b8b6)