mirror of
https://github.com/PaperMC/Paper.git
synced 2024-11-30 20:21:51 +01:00
ff085b8e8e
Timers such as syncChunkLoad are hit persistently due to changes in how this mechanism works which impacts the usablity of timings
317 lines
16 KiB
Diff
317 lines
16 KiB
Diff
From 4e1cc41ed39216510254b9cda8fe10e8a62b1d03 Mon Sep 17 00:00:00 2001
|
|
From: Joseph Hirschfeld <joe@ibj.io>
|
|
Date: Thu, 3 Mar 2016 03:15:41 -0600
|
|
Subject: [PATCH] Add exception reporting event
|
|
|
|
|
|
diff --git a/src/main/java/com/destroystokyo/paper/ServerSchedulerReportingWrapper.java b/src/main/java/com/destroystokyo/paper/ServerSchedulerReportingWrapper.java
|
|
new file mode 100644
|
|
index 000000000..f699ce18c
|
|
--- /dev/null
|
|
+++ b/src/main/java/com/destroystokyo/paper/ServerSchedulerReportingWrapper.java
|
|
@@ -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;
|
|
+ }
|
|
+}
|
|
diff --git a/src/main/java/net/minecraft/server/Chunk.java b/src/main/java/net/minecraft/server/Chunk.java
|
|
index f6f5b72de..ec64391a4 100644
|
|
--- a/src/main/java/net/minecraft/server/Chunk.java
|
|
+++ b/src/main/java/net/minecraft/server/Chunk.java
|
|
@@ -1,5 +1,6 @@
|
|
package net.minecraft.server;
|
|
|
|
+import com.destroystokyo.paper.exception.ServerInternalException;
|
|
import com.google.common.collect.Maps;
|
|
import com.google.common.collect.Sets;
|
|
import it.unimi.dsi.fastutil.longs.LongOpenHashSet;
|
|
@@ -511,10 +512,15 @@ public class Chunk implements IChunkAccess {
|
|
this.tileEntities.remove(blockposition);
|
|
// Paper end
|
|
} else {
|
|
- System.out.println("Attempted to place a tile entity (" + tileentity + ") at " + tileentity.position.getX() + "," + tileentity.position.getY() + "," + tileentity.position.getZ()
|
|
- + " (" + getType(blockposition) + ") where there was no entity tile!");
|
|
- System.out.println("Chunk coordinates: " + (this.loc.x * 16) + "," + (this.loc.z * 16));
|
|
- new Exception().printStackTrace();
|
|
+ // Paper start
|
|
+ ServerInternalException e = new ServerInternalException(
|
|
+ "Attempted to place a tile entity (" + tileentity + ") at " + tileentity.position.getX() + ","
|
|
+ + tileentity.position.getY() + "," + tileentity.position.getZ()
|
|
+ + " (" + getType(blockposition) + ") where there was no entity tile!\n" +
|
|
+ "Chunk coordinates: " + (this.loc.x * 16) + "," + (this.loc.z * 16));
|
|
+ e.printStackTrace();
|
|
+ ServerInternalException.reportInternalException(e);
|
|
+ // Paper end
|
|
// CraftBukkit end
|
|
}
|
|
}
|
|
diff --git a/src/main/java/net/minecraft/server/ChunkProviderServer.java b/src/main/java/net/minecraft/server/ChunkProviderServer.java
|
|
index 60b73bff8..43da95e60 100644
|
|
--- a/src/main/java/net/minecraft/server/ChunkProviderServer.java
|
|
+++ b/src/main/java/net/minecraft/server/ChunkProviderServer.java
|
|
@@ -14,6 +14,9 @@ import java.util.function.BooleanSupplier;
|
|
import java.util.function.Function;
|
|
import java.util.function.Supplier;
|
|
import javax.annotation.Nullable;
|
|
+import com.destroystokyo.paper.exception.ServerInternalException;
|
|
+import org.apache.logging.log4j.LogManager;
|
|
+import org.apache.logging.log4j.Logger;
|
|
|
|
public class ChunkProviderServer extends IChunkProvider {
|
|
|
|
diff --git a/src/main/java/net/minecraft/server/NameReferencingFileConverter.java b/src/main/java/net/minecraft/server/NameReferencingFileConverter.java
|
|
index 2cb0962ff..21a8ed323 100644
|
|
--- a/src/main/java/net/minecraft/server/NameReferencingFileConverter.java
|
|
+++ b/src/main/java/net/minecraft/server/NameReferencingFileConverter.java
|
|
@@ -1,5 +1,6 @@
|
|
package net.minecraft.server;
|
|
|
|
+import com.destroystokyo.paper.exception.ServerInternalException;
|
|
import com.google.common.collect.Lists;
|
|
import com.google.common.collect.Maps;
|
|
import com.google.common.io.Files;
|
|
@@ -354,6 +355,7 @@ public class NameReferencingFileConverter {
|
|
root = NBTCompressedStreamTools.a(new java.io.FileInputStream(file5));
|
|
} catch (Exception exception) {
|
|
exception.printStackTrace();
|
|
+ ServerInternalException.reportInternalException(exception); // Paper
|
|
}
|
|
|
|
if (root != null) {
|
|
@@ -367,6 +369,7 @@ public class NameReferencingFileConverter {
|
|
NBTCompressedStreamTools.a(root, new java.io.FileOutputStream(file2));
|
|
} catch (Exception exception) {
|
|
exception.printStackTrace();
|
|
+ ServerInternalException.reportInternalException(exception); // Paper
|
|
}
|
|
}
|
|
// CraftBukkit end
|
|
diff --git a/src/main/java/net/minecraft/server/PlayerChunkMap.java b/src/main/java/net/minecraft/server/PlayerChunkMap.java
|
|
index 312845ec0..d4122b893 100644
|
|
--- a/src/main/java/net/minecraft/server/PlayerChunkMap.java
|
|
+++ b/src/main/java/net/minecraft/server/PlayerChunkMap.java
|
|
@@ -649,6 +649,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
|
|
this.world.checkSession();
|
|
} catch (ExceptionWorldConflict exceptionworldconflict) {
|
|
PlayerChunkMap.LOGGER.error("Couldn't save chunk; already in use by another instance of Minecraft?", exceptionworldconflict);
|
|
+ com.destroystokyo.paper.exception.ServerInternalException.reportInternalException(exceptionworldconflict); // Paper
|
|
return false;
|
|
}
|
|
|
|
@@ -676,6 +677,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
|
|
return true;
|
|
} catch (Exception exception) {
|
|
PlayerChunkMap.LOGGER.error("Failed to save chunk {},{}", chunkcoordintpair.x, chunkcoordintpair.z, exception);
|
|
+ com.destroystokyo.paper.exception.ServerInternalException.reportInternalException(exception); // Paper
|
|
return false;
|
|
}
|
|
}
|
|
diff --git a/src/main/java/net/minecraft/server/RegionFile.java b/src/main/java/net/minecraft/server/RegionFile.java
|
|
index d4a9af975..88b5aa3a5 100644
|
|
--- a/src/main/java/net/minecraft/server/RegionFile.java
|
|
+++ b/src/main/java/net/minecraft/server/RegionFile.java
|
|
@@ -1,5 +1,6 @@
|
|
package net.minecraft.server;
|
|
|
|
+import com.destroystokyo.paper.exception.ServerInternalException;
|
|
import com.google.common.collect.Lists;
|
|
import java.io.BufferedInputStream;
|
|
import java.io.BufferedOutputStream;
|
|
@@ -142,6 +143,7 @@ public class RegionFile implements AutoCloseable {
|
|
}
|
|
}
|
|
} catch (IOException ioexception) {
|
|
+ ServerInternalException.reportInternalException(ioexception); // Paper
|
|
return null;
|
|
}
|
|
}
|
|
@@ -252,6 +254,7 @@ public class RegionFile implements AutoCloseable {
|
|
this.b(chunkcoordintpair, (int) (SystemUtils.getTimeMillis() / 1000L));
|
|
} catch (IOException ioexception) {
|
|
ioexception.printStackTrace();
|
|
+ ServerInternalException.reportInternalException(ioexception); // Paper
|
|
}
|
|
|
|
}
|
|
diff --git a/src/main/java/net/minecraft/server/SpawnerCreature.java b/src/main/java/net/minecraft/server/SpawnerCreature.java
|
|
index a54d65337..4aa65c193 100644
|
|
--- a/src/main/java/net/minecraft/server/SpawnerCreature.java
|
|
+++ b/src/main/java/net/minecraft/server/SpawnerCreature.java
|
|
@@ -8,6 +8,7 @@ import org.apache.logging.log4j.LogManager;
|
|
import org.apache.logging.log4j.Logger;
|
|
|
|
// CraftBukkit start
|
|
+import com.destroystokyo.paper.exception.ServerInternalException;
|
|
import org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason;
|
|
// CraftBukkit end
|
|
|
|
@@ -83,6 +84,7 @@ public final class SpawnerCreature {
|
|
entityinsentient = (EntityInsentient) entity;
|
|
} catch (Exception exception) {
|
|
SpawnerCreature.LOGGER.warn("Failed to create mob", exception);
|
|
+ ServerInternalException.reportInternalException(exception); // Paper
|
|
return;
|
|
}
|
|
|
|
@@ -210,6 +212,7 @@ public final class SpawnerCreature {
|
|
entity = biomebase_biomemeta.b.a(generatoraccess.getMinecraftWorld());
|
|
} catch (Exception exception) {
|
|
SpawnerCreature.LOGGER.warn("Failed to create mob", exception);
|
|
+ ServerInternalException.reportInternalException(exception); // Paper
|
|
continue;
|
|
}
|
|
|
|
diff --git a/src/main/java/net/minecraft/server/VillageSiege.java b/src/main/java/net/minecraft/server/VillageSiege.java
|
|
index 0a1d342c1..347608531 100644
|
|
--- a/src/main/java/net/minecraft/server/VillageSiege.java
|
|
+++ b/src/main/java/net/minecraft/server/VillageSiege.java
|
|
@@ -1,5 +1,7 @@
|
|
package net.minecraft.server;
|
|
|
|
+import com.destroystokyo.paper.exception.ServerInternalException;
|
|
+
|
|
import java.util.Iterator;
|
|
import javax.annotation.Nullable;
|
|
|
|
@@ -97,6 +99,7 @@ public class VillageSiege {
|
|
entityzombie.prepare(this.a, this.a.getDamageScaler(new BlockPosition(entityzombie)), EnumMobSpawn.EVENT, (GroupDataEntity) null, (NBTTagCompound) null);
|
|
} catch (Exception exception) {
|
|
exception.printStackTrace();
|
|
+ ServerInternalException.reportInternalException(exception); // Paper
|
|
return;
|
|
}
|
|
|
|
diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java
|
|
index c58c95b03..d2062b335 100644
|
|
--- a/src/main/java/net/minecraft/server/World.java
|
|
+++ b/src/main/java/net/minecraft/server/World.java
|
|
@@ -2,6 +2,9 @@ package net.minecraft.server;
|
|
|
|
import co.aikar.timings.Timing;
|
|
import co.aikar.timings.Timings;
|
|
+import com.destroystokyo.paper.event.server.ServerExceptionEvent;
|
|
+import com.destroystokyo.paper.exception.ServerInternalException;
|
|
+import com.google.common.base.MoreObjects;
|
|
import com.google.common.collect.Lists;
|
|
import java.io.IOException;
|
|
import java.util.Collection;
|
|
@@ -715,8 +718,11 @@ public abstract class World implements IIBlockAccess, GeneratorAccess, AutoClose
|
|
gameprofilerfiller.exit();
|
|
} catch (Throwable throwable) {
|
|
// Paper start - Prevent tile entity and entity crashes
|
|
- System.err.println("TileEntity threw exception at " + tileentity.world.getWorld().getName() + ":" + tileentity.position.getX() + "," + tileentity.position.getY() + "," + tileentity.position.getZ());
|
|
+ String msg = "TileEntity threw exception at " + tileentity.world.getWorld().getName() + ":" + tileentity.position.getX() + "," + tileentity.position.getY() + "," + tileentity.position.getZ();
|
|
+ System.err.println(msg);
|
|
throwable.printStackTrace();
|
|
+ getServer().getPluginManager().callEvent(new ServerExceptionEvent(new ServerInternalException(msg, throwable)));
|
|
+ // Paper end
|
|
tilesThisCycle--;
|
|
this.tileEntityListTick.remove(tileTickPosition--);
|
|
continue;
|
|
@@ -787,8 +793,10 @@ public abstract class World implements IIBlockAccess, GeneratorAccess, AutoClose
|
|
consumer.accept(entity);
|
|
} catch (Throwable throwable) {
|
|
// Paper start - Prevent tile entity and entity crashes
|
|
- System.err.println("Entity threw exception at " + entity.world.getWorld().getName() + ":" + entity.locX + "," + entity.locY + "," + entity.locZ);
|
|
+ String msg = "Entity threw exception at " + entity.world.getWorld().getName() + ":" + entity.locX + "," + entity.locY + "," + entity.locZ;
|
|
+ System.err.println(msg);
|
|
throwable.printStackTrace();
|
|
+ getServer().getPluginManager().callEvent(new ServerExceptionEvent(new ServerInternalException(msg, throwable)));
|
|
entity.dead = true;
|
|
return;
|
|
// Paper end
|
|
diff --git a/src/main/java/net/minecraft/server/WorldPersistentData.java b/src/main/java/net/minecraft/server/WorldPersistentData.java
|
|
index f5f540032..00e9a1735 100644
|
|
--- a/src/main/java/net/minecraft/server/WorldPersistentData.java
|
|
+++ b/src/main/java/net/minecraft/server/WorldPersistentData.java
|
|
@@ -121,6 +121,7 @@ public class WorldPersistentData {
|
|
nbttagcompound = GameProfileSerializer.a(this.c, DataFixTypes.SAVED_DATA, nbttagcompound1, j, i);
|
|
} catch (Throwable throwable4) {
|
|
throwable = throwable4;
|
|
+ com.destroystokyo.paper.exception.ServerInternalException.reportInternalException(throwable); // Paper
|
|
throw throwable4;
|
|
} finally {
|
|
if (pushbackinputstream != null) {
|
|
diff --git a/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java b/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java
|
|
index 8823f94f7..552daf437 100644
|
|
--- a/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java
|
|
+++ b/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java
|
|
@@ -16,6 +16,9 @@ import java.util.concurrent.atomic.AtomicInteger;
|
|
import java.util.concurrent.atomic.AtomicReference;
|
|
import java.util.function.Consumer;
|
|
import java.util.logging.Level;
|
|
+import com.destroystokyo.paper.ServerSchedulerReportingWrapper;
|
|
+import com.destroystokyo.paper.event.server.ServerExceptionEvent;
|
|
+import com.destroystokyo.paper.exception.ServerSchedulerException;
|
|
import org.apache.commons.lang.Validate;
|
|
import org.bukkit.plugin.IllegalPluginAccessException;
|
|
import org.bukkit.plugin.Plugin;
|
|
@@ -393,20 +396,26 @@ public class CraftScheduler implements BukkitScheduler {
|
|
try {
|
|
task.run();
|
|
} catch (final Throwable throwable) {
|
|
+ // Paper start
|
|
+ String msg = 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()),
|
|
+ msg,
|
|
throwable);
|
|
+ task.getOwner().getServer().getPluginManager().callEvent(
|
|
+ new ServerExceptionEvent(new ServerSchedulerException(msg, throwable, task))
|
|
+ );
|
|
+ // Paper end
|
|
} finally {
|
|
currentTask = null;
|
|
}
|
|
parsePending();
|
|
} else {
|
|
debugTail = debugTail.setNext(new CraftAsyncDebugger(currentTick + RECENT_TICKS, task.getOwner(), task.getTaskClass()));
|
|
- executor.execute(task);
|
|
+ executor.execute(new 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)
|
|
}
|
|
--
|
|
2.22.0
|
|
|