diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/task/TaskExecutor.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/task/TaskExecutor.java index c8212ac34..257c14e49 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/task/TaskExecutor.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/task/TaskExecutor.java @@ -24,6 +24,7 @@ import java.util.*; import java.util.concurrent.*; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicReference; import java.util.logging.Level; /** @@ -64,7 +65,7 @@ public final class TaskExecutor { public TaskExecutor start() { taskListeners.forEach(TaskListener::onStart); workerQueue.add(scheduler.schedule(() -> { - boolean flag = executeTasks(Collections.singleton(firstTask)); + boolean flag = executeTasks(Collections.singleton(firstTask), new AtomicReference<>()); taskListeners.forEach(it -> it.onStop(flag, this)); })); return this; @@ -74,7 +75,7 @@ public final class TaskExecutor { taskListeners.forEach(TaskListener::onStart); AtomicBoolean flag = new AtomicBoolean(true); Future future = scheduler.schedule(() -> { - flag.set(executeTasks(Collections.singleton(firstTask))); + flag.set(executeTasks(Collections.singleton(firstTask), new AtomicReference<>())); taskListeners.forEach(it -> it.onStop(flag.get(), this)); }); workerQueue.add(future); @@ -100,7 +101,7 @@ public final class TaskExecutor { } } - private boolean executeTasks(Collection tasks) throws InterruptedException { + private boolean executeTasks(Collection tasks, AtomicReference exception) throws InterruptedException { if (tasks.isEmpty()) return true; @@ -128,6 +129,8 @@ public final class TaskExecutor { } catch (InterruptedException e) { return false; } + + exception.set(tasks.stream().map(Task::getLastException).filter(Objects::nonNull).findAny().orElse(null)); return success.get() && !canceled; } @@ -160,9 +163,12 @@ public final class TaskExecutor { } } - boolean doDependentsSucceeded = executeTasks(task.getDependents()); - if (!doDependentsSucceeded && task.isRelyingOnDependents() || canceled) + AtomicReference dependentsException = new AtomicReference<>(); + boolean doDependentsSucceeded = executeTasks(task.getDependents(), dependentsException); + if (!doDependentsSucceeded && task.isRelyingOnDependents() || canceled) { + task.setLastException(dependentsException.get()); throw new SilentException(); + } if (doDependentsSucceeded) task.setDependentsSucceeded(); @@ -187,9 +193,11 @@ public final class TaskExecutor { variables.set(taskResult.getId(), taskResult.getResult()); } - boolean doDependenciesSucceeded = executeTasks(task.getDependencies()); + AtomicReference dependenciesException = new AtomicReference<>(); + boolean doDependenciesSucceeded = executeTasks(task.getDependencies(), dependenciesException); if (!doDependenciesSucceeded && task.isRelyingOnDependencies()) { Logging.LOG.severe("Subtasks failed for " + task.getName()); + task.setLastException(dependenciesException.get()); throw new SilentException(); }