jd-opensource/joyagent-jdgenie · error · RuntimeException

sse listener failed

Error message

sse listener failed 

What it means

runNL2SQLSse streams the NL2SQL request over SSE and waits on the listener's CountDownLatch. If the Nl2SqlSseListener reports failure (isSuccess()==false), the accumulated errorMessage is wrapped in this RuntimeException. It signals the SSE stream itself failed or completed without a successful result event.

Solutions

  1. Inspect the appended sqlSseListener.getErrorMessage() for the stream-level cause
  2. Check agent logs for the requestId included in the request
  3. Confirm no LB/proxy idle timeout is terminating SSE connections; increase timeouts
  4. Retry the request; treat non-success terminal events as retryable if transient

Example fix

// before
throw new RuntimeException("sse listener failed " + sqlSseListener.getErrorMessage());
// after
throw new RuntimeException("sse listener failed: " + sqlSseListener.getErrorMessage() + ", requestId=" + request.getRequestId());
Defensive patterns

Strategy: try-catch

Try / catch

try {
    return nl2SqlService.runNL2SQLSse(request, emitter);
} catch (RuntimeException e) {
    if (e.getMessage().startsWith("sse listener failed")) {
        log.error("sse stream failed: {}", e.getMessage());
        // retry once or notify client of upstream failure
    }
    throw e;
}

Prevention

When it happens

Trigger: After await() returns, sqlSseListener.isSuccess() is false — e.g. the SSE connection failed, an error event was received, or the stream closed before a final NL2SQLResult arrived.

Common situations: Agent crash mid-stream; proxy/gateway cutting long-lived SSE connections; requestId/traceId mismatch handling; agent returning an error event for bad SQL or schema prompts.

Related errors


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

Appendix: source

Thrown at genie-backend/src/main/java/com/jd/genie/service/Nl2SqlService.java:66

        request.setStream(false);
        String jsonResult = OkHttpUtil.postJsonBody(dataAgentConfig.getAgentUrl() + NL2SQL_URL, null, JSONObject.toJSONString(request));
        log.info("{},{} nl2sql result without sse:{}", request.getTraceId(), request.getRequestId(), jsonResult);
        NL2SQLResult nl2SQLResult = JSONObject.parseObject(jsonResult, NL2SQLResult.class);
        if (err.get() != null) {
            throw new RuntimeException("sse nl2sql failed:" + err.get().getMessage());
        }
        return nl2sqlQueryData(request, nl2SQLResult);
    }

    public List<ChatQueryData> runNL2SQLSse(NL2SQLReq request, SseEmitter emitter) throws Exception {
        AtomicReference<Throwable> err = new AtomicReference<>();
        Nl2SqlSseListener sqlSseListener = new Nl2SqlSseListener(emitter, request.getRequestId(), request.getTraceId());
        OkHttpUtil.requestSse(dataAgentConfig.getAgentUrl() + NL2SQL_URL, null, JSONObject.toJSONString(request), sqlSseListener);
        sqlSseListener.getCountDownLatch().await();
        int eventCount = sqlSseListener.getEventCount();
        log.info("{} sse event count:{}", request.getRequestId(), eventCount);
        if (!sqlSseListener.isSuccess()) {
            throw new RuntimeException("sse listener failed " + sqlSseListener.getErrorMessage());
        }
        NL2SQLResult nl2SQLResult = sqlSseListener.getNl2SQLResult();
        if (err.get() != null) {
            throw new RuntimeException("sse nl2sql failed:" + err.get().getMessage());
        }
        return nl2sqlQueryData(request, nl2SQLResult);
    }


    public String replaceFirstMatchedOrThrow(String input, List<String> codeList) {
        if (input == null || codeList == null || codeList.isEmpty()) {
            throw new IllegalArgumentException("nl2sql返回对象为空");
        }

        List<Pattern> patterns = codeList.stream()
                .distinct()
                .map(code -> Pattern.compile("(?i)(?<!`)\\b" + Pattern.quote(code) + "\\b(?!`)"))
                .toList();

View on GitHub (pinned to 2417e0b8b6)