{"record":{"id":"fdf42de2c3e0d895","repo":"jeecgboot/JeecgBoot","slug":"error-fdf42d","errorCode":null,"errorMessage":"调用大模型接口失败:","messagePattern":"调用大模型接口失败:","errorType":"exception","errorClass":"JeecgBootBizTipException","httpStatus":null,"severity":"error","filePath":"jeecg-boot/jeecg-boot-module/jeecg-boot-module-airag/src/main/java/org/jeecg/modules/airag/app/service/impl/AiragChatServiceImpl.java","lineNumber":1494,"sourceCode":"            }\n        } catch (Exception e) {\n            log.error(e.getMessage(), e);\n            // for [QQYUN-9234] MCP服务连接关闭 - 异常时关闭MCP连接\n            finalAiChatParams.closeMcpConnections();\n            // sse\n            SseEmitter emitter = AiragLocalCache.get(AiragConsts.CACHE_TYPE_SSE, requestId);\n            if (null == emitter) {\n                log.warn(\"[AI应用]接收LLM返回会话已关闭{}\", requestId);\n                return;\n            }\n            String errMsg = \"调用大模型接口失败，详情请查看后台日志。\";\n            if(e instanceof JeecgBootException || e instanceof JeecgBootBizTipException){\n                errMsg = e.getMessage();\n            }\n            EventData eventData = new EventData(requestId, null, EventData.EVENT_FLOW_ERROR, chatConversation.getId(), topicId);\n            eventData.setData(EventFlowData.builder().success(false).message(errMsg).build());\n            closeSSE(emitter, eventData);\n            throw new JeecgBootBizTipException(\"调用大模型接口失败:\" + e.getMessage());\n        }\n\n        // 发送消息给前端\n        BiConsumer<String, String> send2Client = (resMessage, eventType) -> {\n            eventType = oConvertUtils.isNotEmpty(eventType) ? eventType : EventData.EVENT_MESSAGE;\n\n            EventData eventData = new EventData(requestId, null, eventType, chatConversation.getId(), topicId);\n            EventMessageData messageEventData = EventMessageData.builder().message(resMessage).build();\n            eventData.setData(messageEventData);\n            eventData.setRequestId(requestId);\n            // sse\n            SseEmitter emitter = AiragLocalCache.get(AiragConsts.CACHE_TYPE_SSE, requestId);\n            if (null == emitter) {\n                log.warn(\"[AI应用]接收LLM返回会话已关闭\");\n                return;\n            }\n            sendMessage2Client(emitter, eventData);\n        };","sourceCodeStart":1476,"sourceCodeEnd":1512,"githubUrl":"https://github.com/jeecgboot/JeecgBoot/blob/96fb33f5ec68516da0b0147da06b2eb0419e063a/jeecg-boot/jeecg-boot-module/jeecg-boot-module-airag/src/main/java/org/jeecg/modules/airag/app/service/impl/AiragChatServiceImpl.java#L1476-L1512","documentation":"This error is thrown by AiragChatServiceImpl when an exception occurs during the LLM streaming/chat operation (aiChatHandler.chat or aiChatHandler.chatByDefaultModel). The method first closes any MCP connections, sends an error event to the SSE emitter, then re-throws as a JeecgBootBizTipException with the original exception message appended. This is the unified error handling for all LLM communication failures during streaming chat.","triggerScenarios":"A chat request triggers aiChatHandler.chat(modelId, messages, params) or chatByDefaultModel(messages, params) which throws. This happens when: the LLM API endpoint is unreachable, the API key is invalid, the model name is wrong, the request payload exceeds token limits, the LLM provider returns a rate limit error, or an MCP service connection fails.","commonSituations":"LLM provider API key expired or revoked. Network connectivity to the LLM endpoint is blocked by firewall. The model ID references a model that doesn't exist on the provider. Rate limiting by the LLM provider. Token limit exceeded for the conversation context. MCP tool server is down.","solutions":["Check the server logs for the detailed exception stack trace and the appended e.getMessage() to identify the specific LLM provider error.","Verify the AI model configuration: API key, endpoint URL, model name are all correct and the model is activated.","Test connectivity to the LLM provider endpoint from the server using curl or a network diagnostic tool.","If rate-limited, reduce request frequency or upgrade the API plan with the provider.","If token limits are exceeded, reduce the conversation history length or use a model with a larger context window."],"exampleFix":"// before — generic catch with no specific error categorization\n} catch (Exception e) {\n    log.error(e.getMessage(), e);\n    throw new JeecgBootBizTipException(\"调用大模型接口失败:\" + e.getMessage());\n}\n\n// after — categorized handling with actionable messages\n} catch (Exception e) {\n    log.error(\"[AI-CHAT] LLM call failed for requestId={}\", requestId, e);\n    String userMsg = translateLlmException(e, \"调用大模型接口失败\");\n    throw new JeecgBootBizTipException(userMsg);\n}","handlingStrategy":"try-catch","validationCode":"// Pre-flight check: verify LLM endpoint is reachable\npublic static boolean isLlmEndpointReachable(String apiUrl, String apiKey) {\n    try {\n        HttpURLConnection conn = (HttpURLConnection) new URL(apiUrl).openConnection();\n        conn.setConnectTimeout(3000);\n        conn.setRequestProperty(\"Authorization\", \"Bearer \" + apiKey);\n        return conn.getResponseCode() > 0;\n    } catch (Exception e) {\n        return false;\n    }\n}","typeGuard":"// Check if the model configuration is complete\npublic static boolean isModelConfigured(AiragModel model) {\n    return model != null\n        && model.getActivateFlag() != null\n        && model.getActivateFlag() == 1\n        && model.getApiKey() != null\n        && !model.getApiKey().isEmpty()\n        && model.getApiUrl() != null\n        && !model.getApiUrl().isEmpty();\n}","tryCatchPattern":"try {\n    // LLM streaming call\n    chatStream = aiChatHandler.chat(modelId, messages, aiChatParams);\n} catch (Exception e) {\n    log.error(\"[AI-CHAT] LLM call failed\", e);\n    finalAiChatParams.closeMcpConnections();\n    // Close SSE with error event\n    closeSSEWithError(emitter, requestId, e.getMessage());\n    // Re-throw for controller-level handling\n    throw new JeecgBootBizTipException(\"调用大模型接口失败: \" + e.getMessage());\n}","preventionTips":["Implement health checks for LLM endpoints before allowing chat requests","Use circuit breakers to fail fast when the LLM provider is down","Validate API key and model configuration at startup","Implement request timeout and token limit validation before sending to the LLM","Monitor LLM provider rate limits and implement backoff strategies"],"tags":["airag","llm","ai","network","streaming"],"backgroundTag":null,"analyzedSha":"96fb33f5ec68516da0b0147da06b2eb0419e063a","analyzedAt":"2026-08-14T00:04:16.786Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}