Waterfall/BungeeCord-Patches/0051-Add-exception-reporting-event.patch
Shane Freeder f49e238640
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:
5e7dcc48 #3382: Use the correct write method for ChatChain in ClientChat packet
5cdba87b #3377: Add additional checks for protocol length limits
2022-08-20 17:43:03 +01:00

700 lines
29 KiB
Diff

From 1e0eebdd511f09952c96780603ec4ba3c50bf051 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 4180c995..90031156 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;
@@ -33,6 +38,7 @@ import net.md_5.bungee.api.ProxyServer;
import net.md_5.bungee.api.connection.ProxiedPlayer;
import net.md_5.bungee.event.EventBus;
import net.md_5.bungee.event.EventHandler;
+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;
@@ -193,10 +199,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[]
@@ -205,18 +210,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;
}
@@ -304,7 +319,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
}
}
}
@@ -444,7 +463,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;
@@ -458,6 +477,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 2c737675..72f14937 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
Assert.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
Assert.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 351d3724..88f1346f 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
Assert.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 fbfbd546..ae85a1d4 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 06784d1e..d4df4c17 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;
@@ -476,7 +478,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.37.2