Waterfall/BungeeCord-Patches/0050-Add-exception-reporting-event.patch
Luccboy 0f9df684e2 Updated Upstream (BungeeCord)
Upstream has released updates that appear to apply and compile correctly.
This update has not been tested by PaperMC and as with ANY update, please do your own testing

BungeeCord Changes:
497c6879 Add (hopefully temporary) queue for plugin messages to server
7b27dfaf #3522: Revert "#3518: Bump io.netty:netty-bom from 4.1.97.Final to 4.1.98.Final"
f9b75c4a Update tests to JUnit 5
2023-09-24 00:29:03 +01:00

700 lines
29 KiB
Diff

From 525b05ca4be2f52ce7819bda4bc52ddb2868c8cf Mon Sep 17 00:00:00 2001
From: theminecoder <theminecoder.dev@gmail.com>
Date: Wed, 22 Apr 2020 14:00:44 +1000
Subject: [PATCH] Add exception reporting event
diff --git a/api/src/main/java/io/github/waterfallmc/waterfall/event/ProxyExceptionEvent.java b/api/src/main/java/io/github/waterfallmc/waterfall/event/ProxyExceptionEvent.java
new file mode 100644
index 00000000..ee6cb5dd
--- /dev/null
+++ b/api/src/main/java/io/github/waterfallmc/waterfall/event/ProxyExceptionEvent.java
@@ -0,0 +1,27 @@
+package io.github.waterfallmc.waterfall.event;
+
+import com.google.common.base.Preconditions;
+import io.github.waterfallmc.waterfall.exception.ProxyException;
+import net.md_5.bungee.api.plugin.Event;
+
+/**
+ * Called whenever an exception is thrown in a recoverable section of the server.
+ */
+public class ProxyExceptionEvent extends Event {
+
+ private ProxyException exception;
+
+ public ProxyExceptionEvent(ProxyException exception) {
+ this.exception = Preconditions.checkNotNull(exception, "exception");
+ }
+
+ /**
+ * Gets the wrapped exception that was thrown.
+ *
+ * @return Exception thrown
+ */
+ public ProxyException getException() {
+ return exception;
+ }
+
+}
diff --git a/api/src/main/java/io/github/waterfallmc/waterfall/exception/ProxyCommandException.java b/api/src/main/java/io/github/waterfallmc/waterfall/exception/ProxyCommandException.java
new file mode 100644
index 00000000..644a4cd6
--- /dev/null
+++ b/api/src/main/java/io/github/waterfallmc/waterfall/exception/ProxyCommandException.java
@@ -0,0 +1,64 @@
+package io.github.waterfallmc.waterfall.exception;
+
+import net.md_5.bungee.api.CommandSender;
+import net.md_5.bungee.api.plugin.Command;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * Thrown when a command throws an exception
+ */
+public class ProxyCommandException extends ProxyException {
+
+ private final Command command;
+ private final CommandSender commandSender;
+ private final String[] arguments;
+
+ public ProxyCommandException(String message, Throwable cause, Command command, CommandSender commandSender, String[] arguments) {
+ super(message, cause);
+ this.commandSender = checkNotNull(commandSender, "commandSender");
+ this.arguments = checkNotNull(arguments, "arguments");
+ this.command = checkNotNull(command, "command");
+ }
+
+ public ProxyCommandException(Throwable cause, Command command, CommandSender commandSender, String[] arguments) {
+ super(cause);
+ this.commandSender = checkNotNull(commandSender, "commandSender");
+ this.arguments = checkNotNull(arguments, "arguments");
+ this.command = checkNotNull(command, "command");
+ }
+
+ protected ProxyCommandException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace, Command command, CommandSender commandSender, String[] arguments) {
+ super(message, cause, enableSuppression, writableStackTrace);
+ this.commandSender = checkNotNull(commandSender, "commandSender");
+ this.arguments = checkNotNull(arguments, "arguments");
+ this.command = checkNotNull(command, "command");
+ }
+
+ /**
+ * Gets the command which threw the exception
+ *
+ * @return exception throwing command
+ */
+ public Command getCommand() {
+ return command;
+ }
+
+ /**
+ * Gets the command sender which executed the command request
+ *
+ * @return command sender of exception thrown command request
+ */
+ public CommandSender getCommandSender() {
+ return commandSender;
+ }
+
+ /**
+ * Gets the arguments which threw the exception for the command
+ *
+ * @return arguments of exception thrown command request
+ */
+ public String[] getArguments() {
+ return arguments;
+ }
+}
diff --git a/api/src/main/java/io/github/waterfallmc/waterfall/exception/ProxyEventException.java b/api/src/main/java/io/github/waterfallmc/waterfall/exception/ProxyEventException.java
new file mode 100644
index 00000000..b9842dc5
--- /dev/null
+++ b/api/src/main/java/io/github/waterfallmc/waterfall/exception/ProxyEventException.java
@@ -0,0 +1,53 @@
+package io.github.waterfallmc.waterfall.exception;
+
+import net.md_5.bungee.api.plugin.Event;
+import net.md_5.bungee.api.plugin.Listener;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * Exception thrown when a server event listener throws an exception
+ */
+//TODO Find a better way to retrieve the plugin for this. Currently the event register/bake process
+// doesnt leave a reference to the plugin so there's no way to know what one is being used at any given time
+public class ProxyEventException extends ProxyException {
+
+ private final Listener listener;
+ private final Event event;
+
+ public ProxyEventException(String message, Throwable cause, Listener listener, Event event) {
+ super(message, cause);
+ this.listener = checkNotNull(listener, "listener");
+ this.event = checkNotNull(event, "event");
+ }
+
+ public ProxyEventException(Throwable cause, Listener listener, Event event) {
+ super(cause);
+ this.listener = checkNotNull(listener, "listener");
+ this.event = checkNotNull(event, "event");
+ }
+
+ protected ProxyEventException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace, Listener listener, Event event) {
+ super(message, cause, enableSuppression, writableStackTrace);
+ this.listener = checkNotNull(listener, "listener");
+ this.event = checkNotNull(event, "event");
+ }
+
+ /**
+ * Gets the listener which threw the exception
+ *
+ * @return event listener
+ */
+ public Listener getListener() {
+ return listener;
+ }
+
+ /**
+ * Gets the event which caused the exception
+ *
+ * @return event
+ */
+ public Event getEvent() {
+ return event;
+ }
+}
diff --git a/api/src/main/java/io/github/waterfallmc/waterfall/exception/ProxyException.java b/api/src/main/java/io/github/waterfallmc/waterfall/exception/ProxyException.java
new file mode 100644
index 00000000..b9fbbbe8
--- /dev/null
+++ b/api/src/main/java/io/github/waterfallmc/waterfall/exception/ProxyException.java
@@ -0,0 +1,23 @@
+package io.github.waterfallmc.waterfall.exception;
+
+/**
+ * Wrapper exception for all exceptions that are thrown by the server.
+ */
+public class ProxyException extends Exception {
+
+ public ProxyException(String message) {
+ super(message);
+ }
+
+ public ProxyException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public ProxyException(Throwable cause) {
+ super(cause);
+ }
+
+ protected ProxyException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
+ super(message, cause, enableSuppression, writableStackTrace);
+ }
+}
diff --git a/api/src/main/java/io/github/waterfallmc/waterfall/exception/ProxyInternalException.java b/api/src/main/java/io/github/waterfallmc/waterfall/exception/ProxyInternalException.java
new file mode 100644
index 00000000..acc64c29
--- /dev/null
+++ b/api/src/main/java/io/github/waterfallmc/waterfall/exception/ProxyInternalException.java
@@ -0,0 +1,34 @@
+package io.github.waterfallmc.waterfall.exception;
+
+import io.github.waterfallmc.waterfall.event.ProxyExceptionEvent;
+import net.md_5.bungee.api.ProxyServer;
+
+/**
+ * Thrown when the internal server throws a recoverable exception.
+ */
+public class ProxyInternalException extends ProxyException {
+
+ public ProxyInternalException(String message) {
+ super(message);
+ }
+
+ public ProxyInternalException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public ProxyInternalException(Throwable cause) {
+ super(cause);
+ }
+
+ protected ProxyInternalException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
+ super(message, cause, enableSuppression, writableStackTrace);
+ }
+
+ public static void reportInternalException(Throwable cause) {
+ try {
+ ProxyServer.getInstance().getPluginManager().callEvent(new ProxyExceptionEvent(new ProxyInternalException(cause)));;
+ } catch (Throwable t) {
+ t.printStackTrace(); // Don't want to rethrow!
+ }
+ }
+}
diff --git a/api/src/main/java/io/github/waterfallmc/waterfall/exception/ProxyPluginEnableDisableException.java b/api/src/main/java/io/github/waterfallmc/waterfall/exception/ProxyPluginEnableDisableException.java
new file mode 100644
index 00000000..54dc7da0
--- /dev/null
+++ b/api/src/main/java/io/github/waterfallmc/waterfall/exception/ProxyPluginEnableDisableException.java
@@ -0,0 +1,20 @@
+package io.github.waterfallmc.waterfall.exception;
+
+import net.md_5.bungee.api.plugin.Plugin;
+
+/**
+ * Thrown whenever there is an exception with any enabling or disabling of plugins.
+ */
+public class ProxyPluginEnableDisableException extends ProxyPluginException {
+ public ProxyPluginEnableDisableException(String message, Throwable cause, Plugin responsiblePlugin) {
+ super(message, cause, responsiblePlugin);
+ }
+
+ public ProxyPluginEnableDisableException(Throwable cause, Plugin responsiblePlugin) {
+ super(cause, responsiblePlugin);
+ }
+
+ protected ProxyPluginEnableDisableException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace, Plugin responsiblePlugin) {
+ super(message, cause, enableSuppression, writableStackTrace, responsiblePlugin);
+ }
+}
\ No newline at end of file
diff --git a/api/src/main/java/io/github/waterfallmc/waterfall/exception/ProxyPluginException.java b/api/src/main/java/io/github/waterfallmc/waterfall/exception/ProxyPluginException.java
new file mode 100644
index 00000000..b0de7a4b
--- /dev/null
+++ b/api/src/main/java/io/github/waterfallmc/waterfall/exception/ProxyPluginException.java
@@ -0,0 +1,36 @@
+package io.github.waterfallmc.waterfall.exception;
+
+import net.md_5.bungee.api.plugin.Plugin;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * Wrapper exception for all cases to which a plugin can be immediately blamed for
+ */
+public class ProxyPluginException extends ProxyException {
+ public ProxyPluginException(String message, Throwable cause, Plugin responsiblePlugin) {
+ super(message, cause);
+ this.responsiblePlugin = checkNotNull(responsiblePlugin, "responsiblePlugin");
+ }
+
+ public ProxyPluginException(Throwable cause, Plugin responsiblePlugin) {
+ super(cause);
+ this.responsiblePlugin = checkNotNull(responsiblePlugin, "responsiblePlugin");
+ }
+
+ protected ProxyPluginException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace, Plugin responsiblePlugin) {
+ super(message, cause, enableSuppression, writableStackTrace);
+ this.responsiblePlugin = checkNotNull(responsiblePlugin, "responsiblePlugin");
+ }
+
+ private final Plugin responsiblePlugin;
+
+ /**
+ * Gets the plugin which is directly responsible for the exception being thrown
+ *
+ * @return plugin which is responsible for the exception throw
+ */
+ public Plugin getResponsiblePlugin() {
+ return responsiblePlugin;
+ }
+}
diff --git a/api/src/main/java/io/github/waterfallmc/waterfall/exception/ProxyPluginMessageException.java b/api/src/main/java/io/github/waterfallmc/waterfall/exception/ProxyPluginMessageException.java
new file mode 100644
index 00000000..9e24e09c
--- /dev/null
+++ b/api/src/main/java/io/github/waterfallmc/waterfall/exception/ProxyPluginMessageException.java
@@ -0,0 +1,64 @@
+package io.github.waterfallmc.waterfall.exception;
+
+import net.md_5.bungee.api.connection.ProxiedPlayer;
+import net.md_5.bungee.api.plugin.Plugin;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * Thrown when an incoming plugin message channel throws an exception
+ */
+public class ProxyPluginMessageException extends ProxyPluginException {
+
+ private final ProxiedPlayer player;
+ private final String channel;
+ private final byte[] data;
+
+ public ProxyPluginMessageException(String message, Throwable cause, Plugin responsiblePlugin, ProxiedPlayer player, String channel, byte[] data) {
+ super(message, cause, responsiblePlugin);
+ this.player = checkNotNull(player, "player");
+ this.channel = checkNotNull(channel, "channel");
+ this.data = checkNotNull(data, "data");
+ }
+
+ public ProxyPluginMessageException(Throwable cause, Plugin responsiblePlugin, ProxiedPlayer player, String channel, byte[] data) {
+ super(cause, responsiblePlugin);
+ this.player = checkNotNull(player, "player");
+ this.channel = checkNotNull(channel, "channel");
+ this.data = checkNotNull(data, "data");
+ }
+
+ protected ProxyPluginMessageException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace, Plugin responsiblePlugin, ProxiedPlayer player, String channel, byte[] data) {
+ super(message, cause, enableSuppression, writableStackTrace, responsiblePlugin);
+ this.player = checkNotNull(player, "player");
+ this.channel = checkNotNull(channel, "channel");
+ this.data = checkNotNull(data, "data");
+ }
+
+ /**
+ * Gets the channel to which the error occurred from recieving data from
+ *
+ * @return exception channel
+ */
+ public String getChannel() {
+ return channel;
+ }
+
+ /**
+ * Gets the data to which the error occurred from
+ *
+ * @return exception data
+ */
+ public byte[] getData() {
+ return data;
+ }
+
+ /**
+ * Gets the player which the plugin message causing the exception originated from
+ *
+ * @return exception player
+ */
+ public ProxiedPlayer getPlayer() {
+ return player;
+ }
+}
diff --git a/api/src/main/java/io/github/waterfallmc/waterfall/exception/ProxySchedulerException.java b/api/src/main/java/io/github/waterfallmc/waterfall/exception/ProxySchedulerException.java
new file mode 100644
index 00000000..0d574ecc
--- /dev/null
+++ b/api/src/main/java/io/github/waterfallmc/waterfall/exception/ProxySchedulerException.java
@@ -0,0 +1,37 @@
+package io.github.waterfallmc.waterfall.exception;
+
+import net.md_5.bungee.api.scheduler.ScheduledTask;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * Thrown when a plugin's scheduler fails with an exception
+ */
+public class ProxySchedulerException extends ProxyPluginException {
+
+ private final ScheduledTask task;
+
+ public ProxySchedulerException(String message, Throwable cause, ScheduledTask task) {
+ super(message, cause, task.getOwner());
+ this.task = checkNotNull(task, "task");
+ }
+
+ public ProxySchedulerException(Throwable cause, ScheduledTask task) {
+ super(cause, task.getOwner());
+ this.task = checkNotNull(task, "task");
+ }
+
+ protected ProxySchedulerException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace, ScheduledTask task) {
+ super(message, cause, enableSuppression, writableStackTrace, task.getOwner());
+ this.task = checkNotNull(task, "task");
+ }
+
+ /**
+ * Gets the task which threw the exception
+ *
+ * @return exception throwing task
+ */
+ public ScheduledTask getTask() {
+ return task;
+ }
+}
diff --git a/api/src/main/java/io/github/waterfallmc/waterfall/exception/ProxyTabCompleteException.java b/api/src/main/java/io/github/waterfallmc/waterfall/exception/ProxyTabCompleteException.java
new file mode 100644
index 00000000..5bf57ec1
--- /dev/null
+++ b/api/src/main/java/io/github/waterfallmc/waterfall/exception/ProxyTabCompleteException.java
@@ -0,0 +1,22 @@
+package io.github.waterfallmc.waterfall.exception;
+
+import net.md_5.bungee.api.CommandSender;
+import net.md_5.bungee.api.plugin.Command;
+
+/**
+ * Called when a tab-complete request throws an exception
+ */
+public class ProxyTabCompleteException extends ProxyCommandException {
+
+ public ProxyTabCompleteException(String message, Throwable cause, Command command, CommandSender commandSender, String[] arguments) {
+ super(message, cause, command, commandSender, arguments);
+ }
+
+ public ProxyTabCompleteException(Throwable cause, Command command, CommandSender commandSender, String[] arguments) {
+ super(cause, command, commandSender, arguments);
+ }
+
+ protected ProxyTabCompleteException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace, Command command, CommandSender commandSender, String[] arguments) {
+ super(message, cause, enableSuppression, writableStackTrace, command, commandSender, arguments);
+ }
+}
diff --git a/api/src/main/java/net/md_5/bungee/api/plugin/PluginManager.java b/api/src/main/java/net/md_5/bungee/api/plugin/PluginManager.java
index c11ce8d3..1ba5b249 100644
--- a/api/src/main/java/net/md_5/bungee/api/plugin/PluginManager.java
+++ b/api/src/main/java/net/md_5/bungee/api/plugin/PluginManager.java
@@ -26,6 +26,11 @@ import java.util.Stack;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.logging.Level;
+import io.github.waterfallmc.waterfall.event.ProxyExceptionEvent; // Waterfall
+import io.github.waterfallmc.waterfall.exception.ProxyCommandException; // Waterfall
+import io.github.waterfallmc.waterfall.exception.ProxyEventException; // Waterfall
+import io.github.waterfallmc.waterfall.exception.ProxyPluginEnableDisableException; // Waterfall
+import io.github.waterfallmc.waterfall.exception.ProxyTabCompleteException; // Waterfall
import lombok.RequiredArgsConstructor;
import net.md_5.bungee.api.ChatColor;
import net.md_5.bungee.api.CommandSender;
@@ -34,6 +39,7 @@ import net.md_5.bungee.api.connection.ProxiedPlayer;
import net.md_5.bungee.event.EventBus;
import net.md_5.bungee.event.EventHandler;
import org.yaml.snakeyaml.LoaderOptions;
+import net.md_5.bungee.event.EventHandlerMethod; //Waterfall - Exception event
import org.yaml.snakeyaml.Yaml;
import org.yaml.snakeyaml.constructor.Constructor;
import org.yaml.snakeyaml.introspector.PropertyUtils;
@@ -194,10 +200,9 @@ public final class PluginManager
}
String[] args = Arrays.copyOfRange( split, 1, split.length );
- try
- {
if ( tabResults == null )
{
+ try { // Waterfall - split command & tab complete exception handlers for exception event
if ( proxy.getConfig().isLogCommands() )
{
proxy.getLogger().log( Level.INFO, "{0} executed command: /{1}", new Object[]
@@ -206,18 +211,28 @@ public final class PluginManager
} );
}
command.execute( sender, args );
+ // Waterfall start - split command & tab complete exception handlers for exception event
+ } catch ( Exception ex ) {
+ sender.sendMessage( ChatColor.RED + "An internal error occurred whilst executing this command, please check the console log for details." );
+ ProxyServer.getInstance().getLogger().log( Level.WARNING, "Error in dispatching command", ex );
+ this.callEvent( new ProxyExceptionEvent( new ProxyCommandException( ex, command, sender, args ) ) ); //Waterfall - throw error event
+ }
+ // Waterfall end
} else if ( commandLine.contains( " " ) && command instanceof TabExecutor )
{
+ try { // Waterfall - split command & tab complete exception handlers for exception event
for ( String s : ( (TabExecutor) command ).onTabComplete( sender, args ) )
{
tabResults.add( s );
}
- }
- } catch ( Exception ex )
- {
+ // Waterfall start - split command & tab complete exception handlers for exception event
+ } catch ( Exception ex ) {
sender.sendMessage( ChatColor.RED + "An internal error occurred whilst executing this command, please check the console log for details." );
ProxyServer.getInstance().getLogger().log( Level.WARNING, "Error in dispatching command", ex );
+ this.callEvent( new ProxyExceptionEvent( new ProxyTabCompleteException( ex, command, sender, args ) ) ); //Waterfall - throw error event
}
+ // Waterfall end
+ }
return true;
}
@@ -305,7 +320,11 @@ public final class PluginManager
} );
} catch ( Throwable t )
{
- ProxyServer.getInstance().getLogger().log( Level.WARNING, "Exception encountered when loading plugin: " + plugin.getDescription().getName(), t );
+ // Waterfall start - throw exception event
+ String msg = "Exception encountered when loading plugin: " + plugin.getDescription().getName();
+ ProxyServer.getInstance().getLogger().log( Level.WARNING, msg, t );
+ this.callEvent( new ProxyExceptionEvent( new ProxyPluginEnableDisableException( msg, t, plugin) ) );
+ // Waterfall end
}
}
}
@@ -445,7 +464,7 @@ public final class PluginManager
Preconditions.checkNotNull( event, "event" );
long start = System.nanoTime();
- eventBus.post( event );
+ eventBus.post( event, this::handleEventException ); //Waterfall - pass exception handler below
event.postCall();
long elapsed = System.nanoTime() - start;
@@ -459,6 +478,14 @@ public final class PluginManager
return event;
}
+ //Waterfall start - Exception handler passed to event bus to fire the exception event
+ private <T extends Event> void handleEventException(String msg, T event, EventHandlerMethod method, Throwable ex) {
+ if( !(event instanceof ProxyExceptionEvent) ) {
+ this.callEvent( new ProxyExceptionEvent( new ProxyEventException( msg, ex, (Listener) method.getListener(), event) ) );
+ }
+ }
+ //Waterfall end
+
/**
* Register a {@link Listener} for receiving called events. Methods in this
* Object which wish to receive events must be annotated with the
diff --git a/event/src/main/java/net/md_5/bungee/event/EventBus.java b/event/src/main/java/net/md_5/bungee/event/EventBus.java
index fb301a44..1187acd0 100644
--- a/event/src/main/java/net/md_5/bungee/event/EventBus.java
+++ b/event/src/main/java/net/md_5/bungee/event/EventBus.java
@@ -34,7 +34,8 @@ public class EventBus
this.logger = ( logger == null ) ? Logger.getLogger( Logger.GLOBAL_LOGGER_NAME ) : logger;
}
- public void post(Object event)
+ // Waterfall - Add generic to signature so we don't have to cast in exception handler
+ public <T> void post(T event, EventExceptionHandler<T> exceptionHandler)
{
EventHandlerMethod[] handlers = byEventBaked.get( event.getClass() );
@@ -55,7 +56,9 @@ public class EventBus
throw new Error( "Method rejected target/argument: " + event, ex );
} catch ( InvocationTargetException ex )
{
- logger.log( Level.WARNING, MessageFormat.format( "Error dispatching event {0} to listener {1}", event, method.getListener() ), ex.getCause() );
+ String msg = MessageFormat.format( "Error dispatching event {0} to listener {1}", event, method.getListener() );
+ logger.log( Level.WARNING, msg, ex.getCause() );
+ if( exceptionHandler != null ) exceptionHandler.handleEventException( msg, event, method, ex ); //Waterfall - call passed exception handler
}
long elapsed = System.nanoTime() - start;
diff --git a/event/src/main/java/net/md_5/bungee/event/EventExceptionHandler.java b/event/src/main/java/net/md_5/bungee/event/EventExceptionHandler.java
new file mode 100644
index 00000000..088fe9b7
--- /dev/null
+++ b/event/src/main/java/net/md_5/bungee/event/EventExceptionHandler.java
@@ -0,0 +1,7 @@
+package net.md_5.bungee.event;
+
+public interface EventExceptionHandler<T> {
+
+ public void handleEventException(String msg, T event, EventHandlerMethod method, Throwable ex);
+
+}
diff --git a/event/src/test/java/net/md_5/bungee/event/EventBusTest.java b/event/src/test/java/net/md_5/bungee/event/EventBusTest.java
index da2aa05d..712da5ae 100644
--- a/event/src/test/java/net/md_5/bungee/event/EventBusTest.java
+++ b/event/src/test/java/net/md_5/bungee/event/EventBusTest.java
@@ -14,14 +14,14 @@ public class EventBusTest
public void testNestedEvents()
{
bus.register( this );
- bus.post( new FirstEvent() );
+ bus.post( new FirstEvent(), null ); // Waterfall - We dont need an exception handler here
assertEquals( 0, latch.getCount() );
}
@EventHandler
public void firstListener(FirstEvent event)
{
- bus.post( new SecondEvent() );
+ bus.post( new SecondEvent(), null ); // Waterfall - We dont need an exception handler here
assertEquals( 1, latch.getCount() );
latch.countDown();
}
@@ -39,4 +39,5 @@ public class EventBusTest
public static class SecondEvent
{
}
+
}
diff --git a/event/src/test/java/net/md_5/bungee/event/EventPriorityTest.java b/event/src/test/java/net/md_5/bungee/event/EventPriorityTest.java
index 3c5d45ea..7467540a 100644
--- a/event/src/test/java/net/md_5/bungee/event/EventPriorityTest.java
+++ b/event/src/test/java/net/md_5/bungee/event/EventPriorityTest.java
@@ -15,7 +15,7 @@ public class EventPriorityTest
{
bus.register( this );
bus.register( new EventPriorityListenerPartner() );
- bus.post( new PriorityTestEvent() );
+ bus.post( new PriorityTestEvent(), null ); // Waterfall - We dont need an exception handler here
assertEquals( 0, latch.getCount() );
}
diff --git a/event/src/test/java/net/md_5/bungee/event/UnregisteringListenerTest.java b/event/src/test/java/net/md_5/bungee/event/UnregisteringListenerTest.java
index 014de202..40792a68 100644
--- a/event/src/test/java/net/md_5/bungee/event/UnregisteringListenerTest.java
+++ b/event/src/test/java/net/md_5/bungee/event/UnregisteringListenerTest.java
@@ -13,7 +13,7 @@ public class UnregisteringListenerTest
{
bus.register( this );
bus.unregister( this );
- bus.post( new TestEvent() );
+ bus.post( new TestEvent(), null ); // Waterfall - We dont need an exception handler here
}
@EventHandler
diff --git a/proxy/src/main/java/net/md_5/bungee/BungeeCord.java b/proxy/src/main/java/net/md_5/bungee/BungeeCord.java
index 5cc308b8..3a86fac8 100644
--- a/proxy/src/main/java/net/md_5/bungee/BungeeCord.java
+++ b/proxy/src/main/java/net/md_5/bungee/BungeeCord.java
@@ -11,6 +11,8 @@ import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import io.github.waterfallmc.waterfall.conf.WaterfallConfiguration;
+import io.github.waterfallmc.waterfall.event.ProxyExceptionEvent;
+import io.github.waterfallmc.waterfall.exception.ProxyPluginEnableDisableException;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelException;
@@ -485,7 +487,11 @@ public class BungeeCord extends ProxyServer
}
} catch ( Throwable t )
{
- getLogger().log( Level.SEVERE, "Exception disabling plugin " + plugin.getDescription().getName(), t );
+ // Waterfall start - throw exception event
+ String msg = "Exception disabling plugin " + plugin.getDescription().getName();
+ getLogger().log( Level.SEVERE, msg, t );
+ pluginManager.callEvent( new ProxyExceptionEvent( new ProxyPluginEnableDisableException( msg, t, plugin) ) );
+ // Waterfall end
}
getScheduler().cancel( plugin );
plugin.getExecutorService().shutdownNow();
diff --git a/proxy/src/main/java/net/md_5/bungee/scheduler/BungeeTask.java b/proxy/src/main/java/net/md_5/bungee/scheduler/BungeeTask.java
index 38b75b51..02ec98fc 100644
--- a/proxy/src/main/java/net/md_5/bungee/scheduler/BungeeTask.java
+++ b/proxy/src/main/java/net/md_5/bungee/scheduler/BungeeTask.java
@@ -3,6 +3,9 @@ package net.md_5.bungee.scheduler;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.logging.Level;
+
+import io.github.waterfallmc.waterfall.event.ProxyExceptionEvent;
+import io.github.waterfallmc.waterfall.exception.ProxySchedulerException;
import lombok.Data;
import net.md_5.bungee.api.ProxyServer;
import net.md_5.bungee.api.plugin.Plugin;
@@ -63,7 +66,11 @@ public class BungeeTask implements Runnable, ScheduledTask
task.run();
} catch ( Throwable t )
{
- ProxyServer.getInstance().getLogger().log( Level.SEVERE, "Task " + this + " encountered an exception", t );
+ //Waterfall start - throw exception event
+ String msg = String.format( "Task %s encountered an exception", this );
+ ProxyServer.getInstance().getLogger().log( Level.SEVERE, msg, t );
+ ProxyServer.getInstance().getPluginManager().callEvent( new ProxyExceptionEvent( new ProxySchedulerException( msg, t, this ) ) );
+ //Waterfall end
}
// If we have a period of 0 or less, only run once
--
2.34.1