diff --git a/spring-ai-model/src/main/java/org/springframework/ai/tool/execution/DefaultToolExecutionExceptionProcessor.java b/spring-ai-model/src/main/java/org/springframework/ai/tool/execution/DefaultToolExecutionExceptionProcessor.java index c3f636afb8b..b42f4f63af9 100644 --- a/spring-ai-model/src/main/java/org/springframework/ai/tool/execution/DefaultToolExecutionExceptionProcessor.java +++ b/spring-ai-model/src/main/java/org/springframework/ai/tool/execution/DefaultToolExecutionExceptionProcessor.java @@ -72,9 +72,13 @@ public String process(ToolExecutionException exception) { if (this.alwaysThrow) { throw exception; } - logger.debug("Exception thrown by tool: {}. Message: {}", exception.getToolDefinition().name(), - exception.getMessage()); - return exception.getMessage(); + String message = exception.getMessage(); + if (message == null || message.isBlank()) { + message = "Exception occurred in tool: " + exception.getToolDefinition().name() + " (" + + cause.getClass().getSimpleName() + ")"; + } + logger.debug("Exception thrown by tool: {}. Message: {}", exception.getToolDefinition().name(), message); + return message; } public static Builder builder() { diff --git a/spring-ai-model/src/test/java/org/springframework/ai/tool/execution/DefaultToolExecutionExceptionProcessorTests.java b/spring-ai-model/src/test/java/org/springframework/ai/tool/execution/DefaultToolExecutionExceptionProcessorTests.java index 40be41e0a37..cf0aca7022f 100644 --- a/spring-ai-model/src/test/java/org/springframework/ai/tool/execution/DefaultToolExecutionExceptionProcessorTests.java +++ b/spring-ai-model/src/test/java/org/springframework/ai/tool/execution/DefaultToolExecutionExceptionProcessorTests.java @@ -60,6 +60,28 @@ void processReturnsMessage() { assertThat(result).isEqualTo(this.toolException.getMessage()); } + @Test + void processReturnsFallbackMessageWhenNull() { + DefaultToolExecutionExceptionProcessor processor = DefaultToolExecutionExceptionProcessor.builder().build(); + + ToolExecutionException exception = new ToolExecutionException(this.toolDefinition, new IllegalStateException()); + + String result = processor.process(exception); + + assertThat(result).isEqualTo("Exception occurred in tool: toolName (IllegalStateException)"); + } + + @Test + void processReturnsFallbackMessageWhenBlank() { + DefaultToolExecutionExceptionProcessor processor = DefaultToolExecutionExceptionProcessor.builder().build(); + + ToolExecutionException exception = new ToolExecutionException(this.toolDefinition, new RuntimeException(" ")); + + String result = processor.process(exception); + + assertThat(result).isEqualTo("Exception occurred in tool: toolName (RuntimeException)"); + } + @Test void processAlwaysThrows() { DefaultToolExecutionExceptionProcessor processor = DefaultToolExecutionExceptionProcessor.builder()