Add exception reporting event

This commit is contained in:
Joseph Hirschfeld
2016-03-03 03:15:41 -06:00
parent 1ae9ee1205
commit 68979dd492
8 changed files with 130 additions and 35 deletions

View File

@@ -0,0 +1,38 @@
package com.destroystokyo.paper;
import com.google.common.base.Preconditions;
import org.bukkit.craftbukkit.scheduler.CraftTask;
import com.destroystokyo.paper.event.server.ServerExceptionEvent;
import com.destroystokyo.paper.exception.ServerSchedulerException;
/**
* Reporting wrapper to catch exceptions not natively
*/
public class ServerSchedulerReportingWrapper implements Runnable {
private final CraftTask internalTask;
public ServerSchedulerReportingWrapper(CraftTask internalTask) {
this.internalTask = Preconditions.checkNotNull(internalTask, "internalTask");
}
@Override
public void run() {
try {
internalTask.run();
} catch (RuntimeException e) {
internalTask.getOwner().getServer().getPluginManager().callEvent(
new ServerExceptionEvent(new ServerSchedulerException(e, internalTask))
);
throw e;
} catch (Throwable t) {
internalTask.getOwner().getServer().getPluginManager().callEvent(
new ServerExceptionEvent(new ServerSchedulerException(t, internalTask))
); //Do not rethrow, since it is not permitted with Runnable#run
}
}
public CraftTask getInternalTask() {
return internalTask;
}
}

View File

@@ -415,20 +415,25 @@ public class CraftScheduler implements BukkitScheduler {
try {
task.run();
} catch (final Throwable throwable) {
// Paper start
final String logMessage = String.format(
"Task #%s for %s generated an exception",
task.getTaskId(),
task.getOwner().getDescription().getFullName());
task.getOwner().getLogger().log(
Level.WARNING,
String.format(
"Task #%s for %s generated an exception",
task.getTaskId(),
task.getOwner().getDescription().getFullName()),
logMessage,
throwable);
org.bukkit.Bukkit.getServer().getPluginManager().callEvent(
new com.destroystokyo.paper.event.server.ServerExceptionEvent(new com.destroystokyo.paper.exception.ServerSchedulerException(logMessage, throwable, task)));
// Paper end
} finally {
this.currentTask = null;
}
this.parsePending();
} else {
this.debugTail = this.debugTail.setNext(new CraftAsyncDebugger(this.currentTick + CraftScheduler.RECENT_TICKS, task.getOwner(), task.getTaskClass()));
this.executor.execute(task);
this.executor.execute(new com.destroystokyo.paper.ServerSchedulerReportingWrapper(task)); // Paper
// We don't need to parse pending
// (async tasks must live with race-conditions if they attempt to cancel between these few lines of code)
}