Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 6 additions & 5 deletions commandsv3/src/main/java/org/wpilib/command3/Binding.java
Original file line number Diff line number Diff line change
Expand Up @@ -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");
}
}
12 changes: 5 additions & 7 deletions commandsv3/src/main/java/org/wpilib/command3/Scheduler.java
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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);
}
Expand Down Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
Loading