Waterfall/BungeeCord-Patches/0049-Add-exception-reportin...

700 lines
29 KiB
Diff

From 21306c26f7c8a4074c9a3d5fbe1991a1d00efb52 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 f25ff75a..b4e101ac 100644
--- a/proxy/src/main/java/net/md_5/bungee/BungeeCord.java
+++ b/proxy/src/main/java/net/md_5/bungee/BungeeCord.java
@@ -10,6 +10,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;
@@ -488,7 +490,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.44.0