SpongePowered / SpongeAPI

A Minecraft plugin API
http://www.spongepowered.org/
MIT License
1.14k stars 342 forks source link

Error Reporting in the API #1504

Open gabizou opened 7 years ago

gabizou commented 7 years ago

Currently, it's a well known fact that the CauseTracker does provide a lot of information with regards to providing exceptions and debugging information for Sponge developers to be able to fix bugs in the implementation. Be it that those bugs are directly our fault, or bugs that are interactions with other mods at play. The issue however, is that there is no way to expose this for plugins to provide a more suitable object use for plugins to provide more useful information, unless they spend the time themselves to make their own error reporting framework.

Internally, Sponge uses the PrettyPrinter from Mixins, but this isn't suitable for the API. Since it is something that is strictly for logging purposes, making the logs provide more formatted information in sections or indented objects requires some manual work.

That being said, what I'd like to be able to provide is an API that can be used both in implementation and from plugins to turn error reports from the following:

/**********************************************************************************************************************************************/
/*                                                 Exception trying to process over a phase!                                                  */
/**********************************************************************************************************************************************/
/* PhaseContext :                                                                                                                             */
/*         - Name: CapturedExplosion                                                                                                          */
/*           Object: CaptureExplosion{explosion=net.minecraft.world.Explosion@3155f420}                                                       */
/*         - Name: CapturedEntities                                                                                                           */
/*           Object: CapturedEntitiesSupplier{Captured=0}                                                                                     */
/*         - Name: CapturedBlocks                                                                                                             */
/*           Object: CapturedBlocksSupplier{Captured=109}                                                                                     */
/*         - Name: Owner                                                                                                                      */
/*           Object: EntityPlayerMP['Bammerbom'/62, l='creative', x=-314,81, y=69,12, z=327,91]                                               */
/*         - Name: Source                                                                                                                     */
/*           Object: EntityTNTPrimed['Block of TNT'/266, l='creative', x=-320,38, y=64,00, z=325,49]                                          */
/* Stacktrace:                                                                                                                                */
/* java.lang.IllegalStateException: Expected to be capturing a block position during an explosion! Please analyze the current phase context.  */
/*     org.spongepowered.common.event.tracking.TrackingUtil.lambda$throwWithContext$3(TrackingUtil.java:471)                                  */
/*     java.util.Optional.orElseThrow(Optional.java:290)                                                                                      */
/*     org.spongepowered.common.event.tracking.phase.general.ExplosionState.spawnEntityOrCapture(ExplosionState.java:296)                     */
/*     org.spongepowered.common.event.tracking.phase.general.GeneralPhase.spawnEntityOrCapture(GeneralPhase.java:358)                         */
/*     org.spongepowered.common.event.tracking.CauseTracker.spawnEntity(CauseTracker.java:632)                                                */
/*     net.minecraft.world.WorldServer.spawnEntity(WorldServer.java:2731)                                                                     */
/*     net.minecraft.block.BlockTNT.redirect$onPrimePostExplosion$zbl000(BlockTNT.java:588)                                                   */
/*     net.minecraft.block.BlockTNT.onBlockDestroyedByExplosion(BlockTNT.java:73)                                                             */
/*     net.minecraft.block.Block.onBlockExploded(Block.java:1720)                                                                             */
/*     net.minecraft.world.Explosion.doExplosionB(Explosion.java:242)                                                                         */
/*     net.minecraft.world.WorldServer.newExplosion(WorldServer.java:3108)                                                                    */
/*     net.minecraft.world.WorldServer.triggerInternalExplosion(WorldServer.java:2710)                                                        */
/*     org.spongepowered.common.interfaces.entity.explosive.IMixinExplosive.detonate(IMixinExplosive.java:53)                                 */
/*     net.minecraft.entity.item.EntityTNTPrimed.redirect$onExplode$zem002(EntityTNTPrimed.java:669)                                          */
/*     net.minecraft.entity.item.EntityTNTPrimed.explode(EntityTNTPrimed.java:114)                                                            */
/*     net.minecraft.entity.item.EntityTNTPrimed.onUpdate(EntityTNTPrimed.java:101)                                                           */
/*     org.spongepowered.common.event.tracking.TrackingUtil.tickEntity(TrackingUtil.java:155)                                                 */
/*     net.minecraft.world.WorldServer.redirect$onCallEntityUpdate$zjp000(WorldServer.java:2900)                                              */
/*     net.minecraft.world.World.updateEntityWithOptionalForce(World.java:4379)                                                               */
/*     net.minecraft.world.WorldServer.updateEntityWithOptionalForce(WorldServer.java:879)                                                    */
/*     net.minecraft.world.World.updateEntity(World.java:2079)                                                                                */
/*     net.minecraft.world.World.updateEntities(World.java:6736)                                                                              */
/*     net.minecraft.world.WorldServer.updateEntities(WorldServer.java:2250)                                                                  */
/*     net.minecraft.server.MinecraftServer.updateTimeLightAndEntities(MinecraftServer.java:794)                                              */
/*     net.minecraft.server.dedicated.DedicatedServer.updateTimeLightAndEntities(DedicatedServer.java:402)                                    */
/*     net.minecraft.server.MinecraftServer.tick(MinecraftServer.java:698)                                                                    */
/*     net.minecraft.server.MinecraftServer.run(MinecraftServer.java:547)                                                                     */
/*     java.lang.Thread.run(Thread.java:745)                                                                                                  */
/**********************************************************************************************************************************************/

Into:


/******************************************************************************************************************************************************************************************************/
/*                                                                            Completing incorrect phase                                                                                              */
/******************************************************************************************************************************************************************************************************/
/* Sponge's tracking system is very dependent on knowing when a change to any world takes place, however, we are attempting to complete a "phase" other than the one we most recently entered. This.  */
/* is an error usually on Sponge's part, so a report is required on the issue tracker on GitHub.                                                                                                      */
/******************************************************************************************************************************************************************************************************/
/* Expected to exit phase: ScheduledTaskPhaseState                                                                                                                                                    */
/* But instead found phase: PlaceBlockPacketState                                                                                                                                                     */
/*                                                                                                                                                                                                    */
/* StackTrace:                                                                                                                                                                                        */
/* java.lang.Exception: null                                                                                                                                                                          */
/*     org.spongepowered.common.event.tracking.CauseTracker.completePhase(CauseTracker.java:209)                                                                                                      */
/*     org.spongepowered.common.SpongeImplHooks.onUtilRunTask(SpongeImplHooks.java:248)                                                                                                               */
/*     net.minecraft.server.MinecraftServer.redirect$onRun$zhh000(MinecraftServer.java:3933)                                                                                                          */
/*     net.minecraft.server.MinecraftServer.func_71190_q(MinecraftServer.java:679)                                                                                                                    */
/*     net.minecraft.server.dedicated.DedicatedServer.func_71190_q(DedicatedServer.java:384)                                                                                                          */
/*     net.minecraft.server.MinecraftServer.func_71217_p(MinecraftServer.java:624)                                                                                                                    */
/*     net.minecraft.server.MinecraftServer.run(MinecraftServer.java:482)                                                                                                                             */
/*     java.lang.Thread.run(Unknown Source)                                                                                                                                                           */
/*                                                                                                                                                                                                    */
/*  Phases Remaining:                                                                                                                                                                                 */
/*   - Phase: PlaceBlockPacketState                                                                                                                                                                   */
/*     Context:                                                                                                                                                                                       */  
/*      Source           = EntityPlayerMP[‘t2wave’ /569, l=‘world’, x=-271.74, y=61.00, z=-760.44]                                                                                                    */
/*      PacketPlayer     = EntityPlayerMP[‘t2wave’ /569, l=‘world’, x=-271.74, y=61.00, z=-760.44]                                                                                                    */
/*      Packet           = CPacketPlayerTryUseItemOnBlock{position=BlockPos{x=-275, y=61, z=-763}, placedBlockDirection=east, hand=MAIN_HAND, facingX=1.0, facingY=0.48047763, facingZ=0.9991058}     */
/*      Cursor           = SpongeItemStackSnapshot{itemType=Item{Name=none}, count=1}                                                                                                                 */
/*      IgnoringCreative = false                                                                                                                                                                      */
/*      ItemUsed         = 1xtile.shulkerBoxMagenta@0                                                                                                                                                 */
/*      CapturedBlocks   = CapturedBlocksSupplier{Captured=0}                                                                                                                                         */
/*      CapturedEntities = CapturedEntitiesSupplier{Captured=0}                                                                                                                                       */
/*      Owner            = EntityPlayerMP['t2wave'/569, l='world', x=-271.74, y=61.00, z=-760.44]                                                                                                     */
/*      Notifier         = EntityPlayerMP['t2wave'/569, l='world', x=-271.74, y=61.00, z=-760.44]                                                                                                     */
/*   - Phase: ScheduledTaskPhaseState                                                                                                                                                                 */
/*     Context:                                                                                                                                                                                       */
/*      Source           = com.google.common.util.concurrent.ListenableFutureTask@59883f9b                                                                                                            */
/*      CapturedBlocks   = CapturedBlocksSupplier{Captured=0}                                                                                                                                         */
/*      CapturedEntities = CapturedEntitiesSupplier{Captured=0}                                                                                                                                       */
/*                                                                                                                                                                                                    */
/*  World: WorldServer                                                                                                                                                                                */
/*    LevelName: world                                                                                                                                                                                */
/*    DimensionId: 0                                                                                                                                                                                  */
/*    DimensionType: minecraft:overworld                                                                                                                                                              */
/*                                                                                                                                                                                                    */
/*  Implementation: SpongeForge                                                                                                                                                                       */
/*  Sponge Version: 1.11.2-2227-6.0.0-BETA-2204                                                                                                                                                       */
/*  API Version: 6.0.0-SNAPSHOT-c641cb0                                                                                                                                                               */
/*  Forge Version: 13.20.0.2204.                                                                                                                                                                      */
/*                                                                                                                                                                                                    */
/*  Plugins:                                                                                                                                                                                          */
/*   - SomeRandomPlugin(v.1.sleepy.0.0.calamitous.1437363538.7)                                                                                                                                       */
/*   - iDontKnowHowToVersion(1.23.100.12.3.16-a-build10)                                                                                                                                              */
/*   - IWasBornThisWay(03.2.34.12-39b23ac8                                                                                                                                                            */
/*   - VoxelSniper(8.0.1-git-5398db29a)                                                                                                                                                               */
/*                                                                                                                                                                                                    */
/*                                                                                                                                                                                                    */
/*  Mods:                                                                                                                                                                                             */
/*   - HowDoIASM(how.do.i.asm10.2.5931.b10)                                                                                                                                                           */
/*   - Thaumcraft(5.1.20b4)                                                                                                                                                                           */
/*   - minecraft{1.11.2} [Minecraft] (minecraft.jar)                                                                                                                                                  */
/*   - mcp{9.19} [Minecraft Coder Pack] (minecraft.jar)                                                                                                                                               */
/*   - FML{8.0.99.99} [Forge Mod Loader] (forge-1.11.2-13.20.0.2252-universal.jar)                                                                                                                    */
/*   - forge{13.20.0.2252} [Minecraft Forge] (forge-1.11.2-13.20.0.2252-universal.jar)                                                                                                                */
/*   - spongeapi{6.0.0-SNAPSHOT-c641cb0} [SpongeAPI] (spongeforge-1.11.2-2227-6.0.0-BETA-2204.jar)                                                                                                    */
/*   - sponge{1.11.2-2227-6.0.0-BETA-2204} [SpongeForge] (spongeforge-1.11.2-2227-6.0.0-BETA-2204.jar)                                                                                                */
/*   - foxcore{0.10.3-208} [FoxCore] (foxcore-0.10.3-208-server.jar)                                                                                                                                  */
/*   - foxguard{0.20.2-api5-347} [FoxGuard] (foxguard-0.20.2-api5-347-server.jar)                                                                                                                     */
/*   - ironchest{1.11-7.0.17.799} [Iron Chest] (ironchest-1.11-7.0.17.799.jar)                                                                                                                        */
/*   - nucleus{0.23.0-PR2-S6.0} [Nucleus] (Nucleus-0.23.0-PR2-1.11.2-S6.0-plugin.jar)                                                                                                                 */
/*   - worldedit{6.1.7-SNAPSHOT} [WorldEdit] (worldedit-sponge-6.1.7-SNAPSHOT-dist.jar)                                                                                                               */
/*                                                                                                                                                                                                    */
/******************************************************************************************************************************************************************************************************/

That being said, I'll be opening a PR with this very description soon after some feedback is given by the community and developers.

Overall however, this would ideally be able to be PRINTED to file so that the reports can simply be copy pasted into a GitHub issue description without having to scroll through potentially hundreds if not thousands of lines of server logs.

Side note as per discussion with @kashike: Note Number 2: There will be a presentational difference to how the reports are presented in the console log versus how they will be presented in the report file itself, namely the borders will be removed when a report is printed to file.

simon816 commented 7 years ago

Having a border is kind of redundant if this is just going to go into its own file anyway.

gabizou commented 7 years ago

Having a border is kind of redundant if this is just going to go into its own file anyway.

Side note as per discussion with @kashike: Note Number 2: There will be a presentational difference to how the reports are presented in the console log versus how they will be presented in the report file itself, namely the borders will be removed when a report is printed to file.

Literally read the description.