From de961b2b7ed4601b13f73d9cecf69297c78a3b70 Mon Sep 17 00:00:00 2001 From: Gold856 <117957790+Gold856@users.noreply.github.com> Date: Tue, 23 Jun 2026 13:45:24 -0400 Subject: [PATCH] [wpilibj] Fix incorrect robot name in reported error (#8294) --- .../java/org/wpilib/framework/RobotBase.java | 30 ++++++++++++++++--- .../org/wpilib/framework/TimedRobotTest.java | 19 ++++++++++++ 2 files changed, 45 insertions(+), 4 deletions(-) diff --git a/wpilibj/src/main/java/org/wpilib/framework/RobotBase.java b/wpilibj/src/main/java/org/wpilib/framework/RobotBase.java index 2b01b926ec..5d97b6a76f 100644 --- a/wpilibj/src/main/java/org/wpilib/framework/RobotBase.java +++ b/wpilibj/src/main/java/org/wpilib/framework/RobotBase.java @@ -303,6 +303,31 @@ public abstract class RobotBase implements AutoCloseable { return robot; } + /** + * Gets the Robot subclass name from a stack trace. + * + * @param elements The stack trace elements to walk. + * @return The Robot subclass name. + */ + protected static String getRobotName(StackTraceElement[] elements) { + // Walk bottom to top to account for multiple layers of subclassing + for (int i = elements.length - 1; i >= 0; i--) { + StackTraceElement element = elements[i]; + try { + // Skip our own class when walking + if (RobotBase.class.equals(Class.forName(element.getClassName()))) { + continue; + } + if (RobotBase.class.isAssignableFrom(Class.forName(element.getClassName()))) { + return element.getClassName(); + } + } catch (ClassNotFoundException e) { + // Unreachable + } + } + return "Unknown"; + } + /** Run the robot main loop. */ @SuppressWarnings("PMD.AvoidCatchingGenericException") private static void runRobot(Class robotClass) { @@ -316,11 +341,8 @@ public abstract class RobotBase implements AutoCloseable { if (cause != null) { throwable = cause; } - String robotName = "Unknown"; StackTraceElement[] elements = throwable.getStackTrace(); - if (elements.length > 0) { - robotName = elements[0].getClassName(); - } + String robotName = getRobotName(elements); DriverStationErrors.reportError( "Unhandled exception instantiating robot " + robotName + " " + throwable, elements); DriverStationErrors.reportError( diff --git a/wpilibj/src/test/java/org/wpilib/framework/TimedRobotTest.java b/wpilibj/src/test/java/org/wpilib/framework/TimedRobotTest.java index b5230e6e7e..30e53051dc 100644 --- a/wpilibj/src/test/java/org/wpilib/framework/TimedRobotTest.java +++ b/wpilibj/src/test/java/org/wpilib/framework/TimedRobotTest.java @@ -130,6 +130,25 @@ class TimedRobotTest { SimHooks.resumeTiming(); } + @Test + void robotNameTest() { + // Simulated stack trace from a robot crash + StackTraceElement[] elements = { + new StackTraceElement("org.wpilib.framework.TimedRobot", "", null, 1), + new StackTraceElement("org.wpilib.framework.TimedRobotTest$MockRobot", "", null, 1), + new StackTraceElement( + "jdk.internal.reflect.DirectConstructorHandleAccessor", "newInstance", null, 1), + new StackTraceElement("java.lang.reflect.Constructor", "newInstanceWithCaller", null, 1), + new StackTraceElement("java.lang.reflect.Constructor", "newInstance", null, 1), + new StackTraceElement("org.wpilib.util.ConstructorMatch", "newInstance", null, 1), + new StackTraceElement("org.wpilib.framework.RobotBase", "constructRobot", null, 1), + new StackTraceElement("org.wpilib.framework.RobotBase", "runRobot", null, 1), + new StackTraceElement("org.wpilib.framework.RobotBase", "lambda$startRobot$0", null, 1), + new StackTraceElement("java.lang.Thread", "run", null, 1) + }; + assertEquals("org.wpilib.framework.TimedRobotTest$MockRobot", MockRobot.getRobotName(elements)); + } + @Test @ResourceLock("timing") void disabledModeTest() {