Add exception wrapper with transparent delivery to the caller

This commit is contained in:
Kai S. K. Engelbart 2022-01-08 14:32:24 +01:00
parent d649f377b7
commit e53f356c54
Signed by: kske
GPG Key ID: 8BEB13EC5DF7EF13
4 changed files with 68 additions and 3 deletions

View File

@ -112,10 +112,11 @@ public final class EventBus {
* *
* @param event the event to dispatch * @param event the event to dispatch
* @throws EventBusException if an event handler isn't accessible or has an invalid signature * @throws EventBusException if an event handler isn't accessible or has an invalid signature
* @throws ExceptionWrapper if it is thrown by an event handler
* @throws NullPointerException if the specified event is {@code null} * @throws NullPointerException if the specified event is {@code null}
* @since 0.0.1 * @since 0.0.1
*/ */
public void dispatch(Object event) throws EventBusException { public void dispatch(Object event) {
Objects.requireNonNull(event); Objects.requireNonNull(event);
logger.log(Level.INFO, "Dispatching event {0}", event); logger.log(Level.INFO, "Dispatching event {0}", event);
@ -140,6 +141,10 @@ public final class EventBus {
// Transparently pass error to the caller // Transparently pass error to the caller
throw (Error) e.getCause(); throw (Error) e.getCause();
else if (e.getCause() instanceof ExceptionWrapper)
// Transparently pass exception wrapper to the caller
throw (ExceptionWrapper) e.getCause();
else if (event instanceof DeadEvent || event instanceof ExceptionEvent) else if (event instanceof DeadEvent || event instanceof ExceptionEvent)
// Warn about system event not being handled // Warn about system event not being handled
@ -214,7 +219,7 @@ public final class EventBus {
* @since 0.0.1 * @since 0.0.1
* @see Event * @see Event
*/ */
public void registerListener(Object listener) throws EventBusException { public void registerListener(Object listener) {
Objects.requireNonNull(listener); Objects.requireNonNull(listener);
if (registeredListeners.contains(listener)) if (registeredListeners.contains(listener))
throw new EventBusException(listener + " already registered!"); throw new EventBusException(listener + " already registered!");

View File

@ -14,13 +14,14 @@ package dev.kske.eventbus.core;
*/ */
public final class EventBusException extends RuntimeException { public final class EventBusException extends RuntimeException {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 7254445250300604449L;
/** /**
* Creates a new event bus exception. * Creates a new event bus exception.
* *
* @param message the message to display * @param message the message to display
* @param cause the cause of this exception * @param cause the cause of this exception
* @since 0.0.1
*/ */
public EventBusException(String message, Throwable cause) { public EventBusException(String message, Throwable cause) {
super(message, cause); super(message, cause);
@ -30,6 +31,7 @@ public final class EventBusException extends RuntimeException {
* Creates a new event bus exception. * Creates a new event bus exception.
* *
* @param message the message to display * @param message the message to display
* @since 0.0.1
*/ */
public EventBusException(String message) { public EventBusException(String message) {
super(message); super(message);

View File

@ -0,0 +1,25 @@
package dev.kske.eventbus.core;
/**
* This unchecked exception acts as a wrapper for an arbitrary exception to prevent an
* {@link ExceptionEvent} from being dispatched. Instead, the wrapped exception is rethrown by
* {@link EventBus#dispatch(Object)}.
*
* @author Kai S. K. Engelbart
* @since 1.2.1
*/
public final class ExceptionWrapper extends RuntimeException {
private static final long serialVersionUID = -2016681140617308788L;
/**
* Creates a new exception wrapper.
*
* @param cause the exception to wrap
* @since 1.2.1
*/
public ExceptionWrapper(Exception cause) {
super(cause);
}
}

View File

@ -0,0 +1,33 @@
package dev.kske.eventbus.core;
import static org.junit.jupiter.api.Assertions.assertThrows;
import org.junit.jupiter.api.Test;
/**
* Tests the behavior of the event bus when an {@link ExceptionWrapper} is thrown.
*
* @author Kai S. K. Engelbart
* @since 1.2.1
*/
public class ExceptionWrapperTest {
EventBus bus = new EventBus();
String event = "This event will cause an exception";
/**
* Tests transparent rethrowing of an exception wrapper by {@link EventBus#dispatch(Object)}.
*
* @since 1.2.1
*/
@Test
public void testExceptionWrapper() {
bus.registerListener(this);
assertThrows(ExceptionWrapper.class, () -> bus.dispatch(event));
}
@Event(String.class)
void onString() {
throw new ExceptionWrapper(new RuntimeException("I failed!"));
}
}