This is an automated email from the ASF dual-hosted git repository.

davsclaus pushed a commit to branch CAMEL-26212-ai-resource-list-binary
in repository https://gitbox.apache.org/repos/asf/camel.git

commit 047bee24141d0b2fd8cdb92369725d2efd9a4b62
Author: Claus Ibsen <[email protected]>
AuthorDate: Tue Nov 3 00:27:29 2026 +0100

    CAMEL-26212: camel-ai-resource - a List body with a binary mimeType gives 
the conversion error that names the resource and the mimeType
    
    For a binary mimeType a List body made getBody(byte[].class) throw a
    TypeConversionException ("argument type mismatch"). It escaped the
    conversionError path and was reported as a generic read error. The
    executor now catches the TypeConversionException for both the String
    and the byte[] conversion and returns the same conversion error as for
    a null result, with the TypeConversionException kept as the cause.
    
    Co-Authored-By: Claude Opus 5.5 <[email protected]>
    Signed-off-by: Claus Ibsen <[email protected]>
---
 .../component/ai/resource/AiResourceExecutor.java  | 25 ++++++++++----
 .../ai/resource/AiResourceExecutorTest.java        | 38 ++++++++++++++++++++++
 2 files changed, 57 insertions(+), 6 deletions(-)

diff --git 
a/components/camel-ai/camel-ai-resource/src/main/java/org/apache/camel/component/ai/resource/AiResourceExecutor.java
 
b/components/camel-ai/camel-ai-resource/src/main/java/org/apache/camel/component/ai/resource/AiResourceExecutor.java
index 5764411a1fa0..a84f65442f63 100644
--- 
a/components/camel-ai/camel-ai-resource/src/main/java/org/apache/camel/component/ai/resource/AiResourceExecutor.java
+++ 
b/components/camel-ai/camel-ai-resource/src/main/java/org/apache/camel/component/ai/resource/AiResourceExecutor.java
@@ -18,6 +18,7 @@ package org.apache.camel.component.ai.resource;
 
 import org.apache.camel.Exchange;
 import org.apache.camel.Processor;
+import org.apache.camel.TypeConversionException;
 import org.apache.camel.support.DefaultConsumer;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -96,27 +97,39 @@ public final class AiResourceExecutor {
         }
 
         if (spec.isTextual()) {
-            String text = exchange.getMessage().getBody(String.class);
+            String text;
+            try {
+                text = exchange.getMessage().getBody(String.class);
+            } catch (TypeConversionException e) {
+                return conversionError(spec, "String", e);
+            }
             if (text == null) {
-                return conversionError(spec, "String");
+                return conversionError(spec, "String", null);
             }
             LOG.debug("Resource '{}' read {} characters", uri, text.length());
             return new AiResourceResult.Text(text);
         }
 
-        byte[] blob = exchange.getMessage().getBody(byte[].class);
+        byte[] blob;
+        try {
+            blob = exchange.getMessage().getBody(byte[].class);
+        } catch (TypeConversionException e) {
+            return conversionError(spec, "byte[]", e);
+        }
         if (blob == null) {
-            return conversionError(spec, "byte[]");
+            return conversionError(spec, "byte[]", null);
         }
         LOG.debug("Resource '{}' read {} bytes", uri, blob.length);
         return new AiResourceResult.Binary(blob);
     }
 
-    private static AiResourceResult conversionError(AiResourceSpec spec, 
String targetType) {
+    private static AiResourceResult conversionError(
+            AiResourceSpec spec, String targetType, TypeConversionException 
conversionFailure) {
         IllegalStateException cause = new IllegalStateException(
                 String.format("Resource '%s' produced a body that cannot be 
converted to %s "
                               + "(declared mimeType is %s)",
-                        spec.getUri(), targetType, spec.getMimeType()));
+                        spec.getUri(), targetType, spec.getMimeType()),
+                conversionFailure);
         return new AiResourceResult.ExecutionError(cause.getMessage(), cause);
     }
 }
diff --git 
a/components/camel-ai/camel-ai-resource/src/test/java/org/apache/camel/component/ai/resource/AiResourceExecutorTest.java
 
b/components/camel-ai/camel-ai-resource/src/test/java/org/apache/camel/component/ai/resource/AiResourceExecutorTest.java
index 9faeaaf080ef..efa55f6dfb0d 100644
--- 
a/components/camel-ai/camel-ai-resource/src/test/java/org/apache/camel/component/ai/resource/AiResourceExecutorTest.java
+++ 
b/components/camel-ai/camel-ai-resource/src/test/java/org/apache/camel/component/ai/resource/AiResourceExecutorTest.java
@@ -17,8 +17,11 @@
 package org.apache.camel.component.ai.resource;
 
 import java.nio.charset.StandardCharsets;
+import java.util.List;
+import java.util.Map;
 
 import org.apache.camel.Exchange;
+import org.apache.camel.TypeConversionException;
 import org.apache.camel.builder.RouteBuilder;
 import org.apache.camel.support.DefaultExchange;
 import org.apache.camel.test.junit6.CamelTestSupport;
@@ -52,6 +55,18 @@ public class AiResourceExecutorTest extends CamelTestSupport 
{
                      + "&mimeType=text/plain")
                         
.setBody(constant("notes".getBytes(StandardCharsets.UTF_8)));
 
+                from("ai-resource:list_as_blob"
+                     + "?resourceUri=camel:///list.bin"
+                     + "&tags=test"
+                     + "&mimeType=application/octet-stream")
+                        .setBody(constant(List.of("a", "b")));
+
+                from("ai-resource:map_as_blob"
+                     + "?resourceUri=camel:///map.bin"
+                     + "&tags=test"
+                     + "&mimeType=application/octet-stream")
+                        .setBody(constant(Map.of("key", "value")));
+
                 from("ai-resource:empty_resource"
                      + "?resourceUri=camel:///empty"
                      + "&tags=test")
@@ -94,6 +109,29 @@ public class AiResourceExecutorTest extends 
CamelTestSupport {
         assertThat(((AiResourceResult.Text) 
result).value()).isEqualTo("notes");
     }
 
+    @Test
+    public void testListBodyWithBinaryMimeTypeIsAConversionError() {
+        AiResourceResult result = read("camel:///list.bin");
+
+        assertThat(result).isInstanceOf(AiResourceResult.ExecutionError.class);
+        AiResourceResult.ExecutionError error = 
(AiResourceResult.ExecutionError) result;
+        String expected = "Resource 'camel:///list.bin' produced a body that 
cannot be converted to byte[]"
+                          + " (declared mimeType is application/octet-stream)";
+        assertThat(error.message()).isEqualTo(expected);
+        assertThat(error.cause()).isInstanceOf(IllegalStateException.class)
+                .hasCauseInstanceOf(TypeConversionException.class);
+    }
+
+    @Test
+    public void testMapBodyWithBinaryMimeTypeIsAConversionError() {
+        AiResourceResult result = read("camel:///map.bin");
+
+        assertThat(result).isInstanceOf(AiResourceResult.ExecutionError.class);
+        String expected = "Resource 'camel:///map.bin' produced a body that 
cannot be converted to byte[]"
+                          + " (declared mimeType is application/octet-stream)";
+        assertThat(((AiResourceResult.ExecutionError) 
result).message()).isEqualTo(expected);
+    }
+
     @Test
     public void testEmptyBodyIsAnError() {
         AiResourceResult result = read("camel:///empty");

Reply via email to