Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,9 @@ private Map<String, Object> executeSqlQuery(OverAllState state, Integer currentS
.flatMapMany(executed -> Flux.concat(baseResultResponses(executed.resultSet()),
chartUpdateResponses(state, executed.resultSet())))
.onErrorResume(e -> {
String errorMessage = e.getMessage();
// NPE / StackOverflowError and several JDBC wrappers carry a null message;
// fall back to the exception type so the user never sees the literal "null"
String errorMessage = StringUtils.isNotBlank(e.getMessage()) ? e.getMessage() : e.getClass().getName();
log.error("SQL execution failed - SQL as follows: \n {} \n ", sqlQuery, e);
result.put(SQL_REGENERATE_REASON, SqlRetryDto.sqlExecute(errorMessage));
return Flux.just(ChatResponseUtil.createResponse("SQL执行失败: " + errorMessage));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,26 @@ void apply_sqlExecutionError_setsRetryReason() throws Exception {
assertFalse(execution.finalResult().containsKey(PLAN_CURRENT_STEP));
}

@Test
void apply_sqlExecutionErrorWithoutMessage_doesNotLeakNullIntoUserFacingText() throws Exception {
OverAllState state = createTestState();
setupBasicState(state);
setupBasicMocks();

// NPE / StackOverflowError and several JDBC wrappers carry a null message
when(accessor.executeSqlAndReturnObject(any(), any())).thenThrow(new RuntimeException((String) null));

NodeExecution execution = execute(sqlExecuteNode.apply(state), SQL_EXECUTE_NODE_OUTPUT);

String streamed = execution.streamedText();
assertFalse(streamed.contains("null"),
"user-facing text must not leak the literal 'null', was: " + streamed);
assertTrue(streamed.contains("SQL执行失败"), "failure notice must still be emitted, was: " + streamed);
SqlRetryDto retryReason = (SqlRetryDto) execution.finalResult().get(SQL_REGENERATE_REASON);
assertNotNull(retryReason);
assertTrue(retryReason.sqlExecuteFail());
}

@Test
void apply_connectionFailure_throwsException() throws Exception {
OverAllState state = createTestState();
Expand Down
Loading