Skip to content

Commit afbae57

Browse files
authored
fix: fail when adding null component event listener (#17276)
Currently, it is possible to add component event listeners pointing to a null reference. At runtime an NPE is thrown, but for an internal wrapper class, making difficult to spot where the null reference comes from. This change will throw immediately if null is given as a component event listener.
1 parent da87e32 commit afbae57

File tree

3 files changed

+21
-2
lines changed

3 files changed

+21
-2
lines changed

flow-server/src/main/java/com/vaadin/flow/component/ComponentEventBus.java

+5
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,11 @@ private <T extends ComponentEvent<?>> Registration addListenerInternal(
141141
Class<T> eventType, ComponentEventListener<T> listener,
142142
Consumer<DomListenerRegistration> domListenerConsumer) {
143143

144+
if (listener == null) {
145+
throw new IllegalArgumentException(
146+
"component event listener cannot be null");
147+
}
148+
144149
ListenerWrapper<T> wrapper = new ListenerWrapper<>(listener);
145150

146151
boolean isDomEvent = addDomTriggerIfNeeded(eventType, wrapper);

flow-server/src/test/java/com/vaadin/flow/component/ComponentEventBusTest.java

+14
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,9 @@
2121
import java.util.concurrent.atomic.AtomicReference;
2222

2323
import org.junit.Assert;
24+
import org.junit.Rule;
2425
import org.junit.Test;
26+
import org.junit.rules.ExpectedException;
2527
import org.mockito.MockedStatic;
2628
import org.mockito.Mockito;
2729

@@ -41,6 +43,9 @@
4143

4244
public class ComponentEventBusTest {
4345

46+
@Rule
47+
public ExpectedException exceptionRule = ExpectedException.none();
48+
4449
private static class EventTracker<T extends ComponentEvent<?>>
4550
implements ComponentEventListener<T> {
4651
private AtomicInteger eventHandlerCalled = new AtomicInteger(0);
@@ -740,4 +745,13 @@ public void addListener_eventDataExpressionsPresent_constantPoolKeyNotCreatedAft
740745
util.verifyNoInteractions();
741746
}
742747
}
748+
749+
@Test
750+
public void addListener_nullListener_failFast() {
751+
exceptionRule.expect(IllegalArgumentException.class);
752+
exceptionRule.expectMessage("component event listener cannot be null");
753+
754+
final TestButton button = new TestButton();
755+
button.addListener(ServerEvent.class, null);
756+
}
743757
}

flow-server/src/test/java/com/vaadin/flow/component/ShortcutRegistrationTest.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -585,10 +585,10 @@ public void reattachComponent_detachListenerIsAddedOnEveryAttach_listenOnUIIsClo
585585

586586
Registration registration = Mockito.mock(Registration.class);
587587
AtomicInteger count = new AtomicInteger();
588-
Mockito.when(ui.addDetachListener(any())).thenAnswer(invocation -> {
588+
Mockito.doAnswer(invocation -> {
589589
count.incrementAndGet();
590590
return registration;
591-
});
591+
}).when(ui).addDetachListener(any());
592592

593593
Component[] components = new Component[] { ui };
594594

0 commit comments

Comments
 (0)