Waterfall/BungeeCord-Patches/0054-Add-exception-reporting-event.patch
Luccboy f7c7b4820c
Updated Upstream (BungeeCord) (#643)
Upstream has released updates that appears 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:
5823f474 #3090: Register events in parent classes
a0b7f092 #3087: Force-enable multi-release jar file support for JDK9+ via System property
2021-05-21 08:58:24 +01:00

700 lines
29 KiB
Diff

From e6d62e8999fba8fdb5409175d81238ddd383404b 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 8da5f275..d28fd528 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() );
@@ -53,7 +54,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
}
}
}
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 eeb63c43..c09f5b4c 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 67db0cc4..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, String.format( "Task %s encountered an exception", this ), 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.31.1.windows.1