Leave ThreadDead alone!

The original intent of catching throwable is to "sandbox" arbitrary
plugin logic and prevent it from ever accidentally killing threads on
the server. A LinkageError due to a missing or old dependency shouldn't
bring down the server, so we secure it by catching all exceptions around
plugin event handlers.

Trouble is, this also catches exceptions such as OutOfMemoryError or
ThreadDead, which assuredly should NOT be caught. The latter case has
even occured in the wild as seen by ticket 45 of TagAPI on BukkitDev.
Minecraft may terminate the reader and writer thread by calling stop(),
and this could occur within the event handler in a plugin. So we should
let ThreadDead go and propagate it to the appropriate handler in
Minecraft.
This commit is contained in:
Kristian S. Stangeland 2013-04-14 03:53:27 +02:00
parent 37dd46432a
commit 5ca29ef5ce

View File

@ -52,6 +52,11 @@ public final class SortedPacketListenerList extends AbstractConcurrentListenerMu
try { try {
event.setReadOnly(element.getPriority() == ListenerPriority.MONITOR); event.setReadOnly(element.getPriority() == ListenerPriority.MONITOR);
element.getListener().onPacketReceiving(event); element.getListener().onPacketReceiving(event);
} catch (OutOfMemoryError e) {
throw e;
} catch (ThreadDeath e) {
throw e;
} catch (Throwable e) { } catch (Throwable e) {
// Minecraft doesn't want your Exception. // Minecraft doesn't want your Exception.
reporter.reportMinimal(element.getListener().getPlugin(), "onPacketReceiving(PacketEvent)", e, reporter.reportMinimal(element.getListener().getPlugin(), "onPacketReceiving(PacketEvent)", e,
@ -78,6 +83,11 @@ public final class SortedPacketListenerList extends AbstractConcurrentListenerMu
event.setReadOnly(element.getPriority() == ListenerPriority.MONITOR); event.setReadOnly(element.getPriority() == ListenerPriority.MONITOR);
element.getListener().onPacketReceiving(event); element.getListener().onPacketReceiving(event);
} }
} catch (OutOfMemoryError e) {
throw e;
} catch (ThreadDeath e) {
throw e;
} catch (Throwable e) { } catch (Throwable e) {
// Minecraft doesn't want your Exception. // Minecraft doesn't want your Exception.
reporter.reportMinimal(element.getListener().getPlugin(), "onPacketReceiving(PacketEvent)", e, reporter.reportMinimal(element.getListener().getPlugin(), "onPacketReceiving(PacketEvent)", e,
@ -101,6 +111,11 @@ public final class SortedPacketListenerList extends AbstractConcurrentListenerMu
try { try {
event.setReadOnly(element.getPriority() == ListenerPriority.MONITOR); event.setReadOnly(element.getPriority() == ListenerPriority.MONITOR);
element.getListener().onPacketSending(event); element.getListener().onPacketSending(event);
} catch (OutOfMemoryError e) {
throw e;
} catch (ThreadDeath e) {
throw e;
} catch (Throwable e) { } catch (Throwable e) {
// Minecraft doesn't want your Exception. // Minecraft doesn't want your Exception.
reporter.reportMinimal(element.getListener().getPlugin(), "onPacketSending(PacketEvent)", e, reporter.reportMinimal(element.getListener().getPlugin(), "onPacketSending(PacketEvent)", e,
@ -127,6 +142,11 @@ public final class SortedPacketListenerList extends AbstractConcurrentListenerMu
event.setReadOnly(element.getPriority() == ListenerPriority.MONITOR); event.setReadOnly(element.getPriority() == ListenerPriority.MONITOR);
element.getListener().onPacketSending(event); element.getListener().onPacketSending(event);
} }
} catch (OutOfMemoryError e) {
throw e;
} catch (ThreadDeath e) {
throw e;
} catch (Throwable e) { } catch (Throwable e) {
// Minecraft doesn't want your Exception. // Minecraft doesn't want your Exception.
reporter.reportMinimal(element.getListener().getPlugin(), "onPacketSending(PacketEvent)", e, reporter.reportMinimal(element.getListener().getPlugin(), "onPacketSending(PacketEvent)", e,