Skip to content

Commit d72d386

Browse files
authored
Merge pull request #50669 from matejvasek/fixes-funqy
Better error message for Funq when using `Byte[]` instead of `byte[]`
2 parents fce1eeb + 9950e16 commit d72d386

File tree

6 files changed

+128
-0
lines changed

6 files changed

+128
-0
lines changed
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
package io.quarkus.funqy.test;
2+
3+
import static org.junit.jupiter.api.Assertions.assertTrue;
4+
import static org.junit.jupiter.api.Assertions.fail;
5+
6+
import org.junit.jupiter.api.Test;
7+
import org.junit.jupiter.api.extension.RegisterExtension;
8+
9+
import io.quarkus.test.QuarkusUnitTest;
10+
11+
public class BadBinaryArrayTest {
12+
@RegisterExtension
13+
static QuarkusUnitTest test1 = assertException(BadBinaryOutputCE.class);
14+
@RegisterExtension
15+
static QuarkusUnitTest test2 = assertException(BadBinaryOutputRaw.class);
16+
@RegisterExtension
17+
static QuarkusUnitTest test3 = assertException(BadBinaryInputCE.class);
18+
@RegisterExtension
19+
static QuarkusUnitTest test4 = assertException(BadBinaryInputRaw.class);
20+
21+
private static QuarkusUnitTest assertException(Class<?> clazz) {
22+
return new QuarkusUnitTest()
23+
.withApplicationRoot(jar -> jar.addClass(clazz))
24+
.assertException(throwable -> {
25+
// Traverse the cause chain to find the IllegalStateException
26+
Throwable current = throwable;
27+
IllegalStateException foundException = null;
28+
29+
while (current != null) {
30+
if (current instanceof IllegalStateException) {
31+
foundException = (IllegalStateException) current;
32+
break;
33+
}
34+
current = current.getCause();
35+
}
36+
37+
if (foundException == null) {
38+
fail("Expected IllegalStateException but got: " + throwable);
39+
}
40+
41+
String message = foundException.getMessage();
42+
if (message == null) {
43+
fail("Exception message is null");
44+
}
45+
46+
// Verify the exception message mentions the issue with Byte[] vs byte[]
47+
if (!message.contains("Byte[]") || !message.contains("byte[]")) {
48+
fail("Exception message should mention both 'Byte[]' and 'byte[]'. Got: " + message);
49+
}
50+
});
51+
}
52+
53+
@Test
54+
void test() {
55+
assertTrue(true);
56+
}
57+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package io.quarkus.funqy.test;
2+
3+
import io.quarkus.funqy.Funq;
4+
import io.quarkus.funqy.knative.events.CloudEvent;
5+
import io.quarkus.funqy.knative.events.CloudEventMapping;
6+
7+
public class BadBinaryInputCE {
8+
@Funq
9+
@CloudEventMapping(trigger = "test-bad-input-ce")
10+
public void badInputCE(CloudEvent<Byte[]> data) {
11+
}
12+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package io.quarkus.funqy.test;
2+
3+
import io.quarkus.funqy.Funq;
4+
import io.quarkus.funqy.knative.events.CloudEventMapping;
5+
6+
public class BadBinaryInputRaw {
7+
@Funq
8+
@CloudEventMapping(trigger = "test-bad-input-raw")
9+
public void badInputRaw(Byte[] data) {
10+
}
11+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package io.quarkus.funqy.test;
2+
3+
import io.quarkus.funqy.Funq;
4+
import io.quarkus.funqy.knative.events.CloudEvent;
5+
import io.quarkus.funqy.knative.events.CloudEventBuilder;
6+
import io.quarkus.funqy.knative.events.CloudEventMapping;
7+
8+
public class BadBinaryOutputCE {
9+
@Funq
10+
@CloudEventMapping(trigger = "test-bad-output-ce")
11+
public CloudEvent<Byte[]> badOutputCE() {
12+
return CloudEventBuilder.create()
13+
.specVersion("1.0")
14+
.id("test-bad-output-ce")
15+
.type("badOutputCE")
16+
.source("/badOutputCE")
17+
.build(new Byte[] {});
18+
}
19+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package io.quarkus.funqy.test;
2+
3+
import io.quarkus.funqy.Funq;
4+
import io.quarkus.funqy.knative.events.CloudEventMapping;
5+
6+
public class BadBinaryOutputRaw {
7+
@Funq
8+
@CloudEventMapping(trigger = "test-bad-output-raw")
9+
public Byte[] badOutputRaw() {
10+
return new Byte[] {};
11+
}
12+
}

extensions/funqy/funqy-knative-events/runtime/src/main/java/io/quarkus/funqy/runtime/bindings/knative/events/KnativeEventsBindingRecorder.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,8 @@ public void init() {
127127
}
128128
}
129129

130+
validateNotBoxedByteArray(inputType, invoker.getName(), "input");
131+
130132
JavaType javaInputType = objectMapper.constructType(inputType);
131133
ObjectReader reader = objectMapper.readerFor(javaInputType);
132134
invoker.getBindingContext().put(DATA_OBJECT_READER, reader);
@@ -148,6 +150,8 @@ public void init() {
148150
}
149151
}
150152

153+
validateNotBoxedByteArray(outputType, invoker.getName(), "output");
154+
151155
JavaType outputJavaType = objectMapper.constructType(outputType);
152156
ObjectWriter writer = objectMapper.writerFor(outputJavaType);
153157
invoker.getBindingContext().put(DATA_OBJECT_WRITER, writer);
@@ -278,4 +282,17 @@ private boolean hasSameFilters(String name, List<Predicate<CloudEvent>> one, Lis
278282
}
279283
return result;
280284
}
285+
286+
private void validateNotBoxedByteArray(Type type, String functionName, String paramType) {
287+
Class<?> rawType = Reflections.getRawType(type);
288+
if (rawType != null && rawType.isArray()) {
289+
Class<?> componentType = rawType.getComponentType();
290+
if (Byte.class.equals(componentType)) {
291+
throw new IllegalStateException(
292+
"Function '" + functionName + "' has " + paramType + " type 'Byte[]' (boxed byte array). " +
293+
"Use 'byte[]' (primitive byte array) instead. " +
294+
"Byte[] is not supported for binary data handling in Funqy Knative Events.");
295+
}
296+
}
297+
}
281298
}

0 commit comments

Comments
 (0)