diff --git a/commandsv3/src/main/java/org/wpilib/command3/Binding.java b/commandsv3/src/main/java/org/wpilib/command3/Binding.java index 4d79496612e..d281890fe1d 100644 --- a/commandsv3/src/main/java/org/wpilib/command3/Binding.java +++ b/commandsv3/src/main/java/org/wpilib/command3/Binding.java @@ -12,15 +12,16 @@ * @param scope The scope in which the binding is active. * @param type The type of binding; or, when the bound command should run * @param command The bound command. Cannot be null. - * @param frames The stack frames when the binding was created. Used for telemetry and error - * reporting so if a command throws an exception, we can tell users where that command was bound - * instead of giving a fairly useless backtrace of the command framework. + * @param stackTraceStore A {@link Throwable} storing stack frames when the binding was created. + * Used for telemetry and error reporting so if a command throws an exception, we can tell users + * where that command was bound instead of giving a fairly useless backtrace of the command + * framework. */ -record Binding(BindingScope scope, BindingType type, Command command, StackTraceElement[] frames) { +record Binding(BindingScope scope, BindingType type, Command command, Throwable stackTraceStore) { public Binding { ErrorMessages.requireNonNullParam(scope, "scope", "Binding"); ErrorMessages.requireNonNullParam(type, "type", "Binding"); ErrorMessages.requireNonNullParam(command, "command", "Binding"); - ErrorMessages.requireNonNullParam(frames, "frames", "Binding"); + ErrorMessages.requireNonNullParam(stackTraceStore, "stackTraceStore", "Binding"); } } diff --git a/commandsv3/src/main/java/org/wpilib/command3/Scheduler.java b/commandsv3/src/main/java/org/wpilib/command3/Scheduler.java index 232c8c1a8e8..31001b1b21d 100644 --- a/commandsv3/src/main/java/org/wpilib/command3/Scheduler.java +++ b/commandsv3/src/main/java/org/wpilib/command3/Scheduler.java @@ -220,10 +220,7 @@ public void setDefaultCommand(Mechanism mechanism, Command defaultCommand) { var binding = new Binding( - scope, - BindingType.CONTINUOUSLY_SCHEDULE_WHILE_HIGH, - defaultCommand, - new Throwable().getStackTrace()); + scope, BindingType.CONTINUOUSLY_SCHEDULE_WHILE_HIGH, defaultCommand, new Throwable()); var currentDefaultCommand = getDefaultCommandFor(mechanism); m_defaultCommandBindings.computeIfAbsent(mechanism, k -> new ArrayList<>()).add(binding); @@ -559,8 +556,7 @@ public ScheduleResult schedule(Command command) { // Note: we use a throwable here instead of Thread.currentThread().getStackTrace() for easier // stack frame filtering and modification. - var binding = - new Binding(scope, BindingType.IMMEDIATE, command, new Throwable().getStackTrace()); + var binding = new Binding(scope, BindingType.IMMEDIATE, command, new Throwable()); return schedule(binding); } @@ -1015,7 +1011,9 @@ private void handleCommandException(CommandState state, RuntimeException e) { // Intercept the exception, inject stack frames from the schedule site, and rethrow it var binding = state.binding(); - e.setStackTrace(CommandTraceHelper.modifyTrace(e.getStackTrace(), binding.frames())); + e.setStackTrace( + CommandTraceHelper.modifyTrace( + e.getStackTrace(), binding.stackTraceStore().getStackTrace())); emitCompletedWithErrorEvent(command, e); // Clean up child commands after emitting the event so child Canceled events are emitted diff --git a/commandsv3/src/main/java/org/wpilib/command3/Trigger.java b/commandsv3/src/main/java/org/wpilib/command3/Trigger.java index 1c6da4f9505..fb85d83d3dd 100644 --- a/commandsv3/src/main/java/org/wpilib/command3/Trigger.java +++ b/commandsv3/src/main/java/org/wpilib/command3/Trigger.java @@ -551,7 +551,7 @@ void addBinding(BindingScope scope, BindingType bindingType, Command command) { // stack frame filtering and modification. m_bindings .computeIfAbsent(bindingType, _k -> new ArrayList<>()) - .add(new Binding(scope, bindingType, command, new Throwable().getStackTrace())); + .add(new Binding(scope, bindingType, command, new Throwable())); if (!m_bound) { // Ensure we're bound to the event loop.