Commit c334349
fix(core): propagate continuous task failures to dependent tasks (#33492)
## Current Behavior
When a continuous task depends on another continuous task and the
dependent task exits with an error, the parent task continues running
indefinitely. The task execution never terminates, leaving processes
running in the background.
For example, if task `a` (continuous) depends on task `b` (continuous),
and task `b` exits with error code 1, task `a` will continue running
even though its dependency failed.
## Expected Behavior
When a continuous task exits (with any exit code), the failure should be
propagated to dependent tasks:
1. The failed continuous task should be marked as failed
2. Dependent continuous tasks should be marked as skipped
3. All affected continuous tasks should be killed
4. Task execution should terminate with an error
---
## Changes Made
### 1. Restore Error Handling in Continuous Task Exit Handlers
- Re-added the `cleaningUp` flag that was removed in a previous
TUI-related commit
- Modified `onExit` handlers for both regular and shared continuous
tasks to:
- Check if the task exited during normal cleanup vs. unexpectedly
- Call `complete()` with 'failure' status for unexpected exits
- Log error messages for debugging
### 2. Fix `cleanUpUnneededContinuousTasks()` Logic
The previous implementation always added `initializingTaskIds` to the
needed set, even when those tasks were already completed. This prevented
dependency tasks from being killed when the top-level task exited.
Fixed by:
- Only adding tasks from `initializingTaskIds` if they are still
incomplete
- Keeping dependencies of incomplete tasks alive
- This ensures continuous tasks are killed when no longer needed,
whether a dependency fails or a top-level task exits
### 3. Prevent Status Overwrites
Added a check in `onExit` handlers to only set status to `Stopped` if
the task hasn't already been completed. This prevents the async `onExit`
callback from overwriting the correct status (like 'skipped' or
'failure') with 'Stopped'.
### 4. Fix Signal Handling in `PseudoTtyProcess.kill()`
The Rust pseudo-terminal defaults to SIGINT when no signal is provided,
which does not reliably terminate child processes in PTY sessions.
Fixed by:
- Defaulting to SIGTERM in the JavaScript wrapper (rather than changing
the Rust default)
- The JS wrapper is the API boundary that should match Node.js
semantics, where `childProcess.kill(undefined)` defaults to SIGTERM
- The Rust default of SIGINT is appropriate for interactive use
(Ctrl-C), while programmatic cleanup needs SIGTERM
- This ensures child processes are properly killed when
`runningTask.kill()` is called
**File:** `packages/nx/src/tasks-runner/pseudo-terminal.ts`
## Technical Details
The fix leverages the existing task failure propagation mechanism in
`complete()` instead of using `process.exit(1)`, which:
- Allows proper cleanup through normal execution flow
- Respects the `--bail` flag configuration
- Works correctly with both TUI and non-TUI modes
- Maintains consistency with how other task failures are handled1 parent e993d05 commit c334349
2 files changed
Lines changed: 30 additions & 6 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
191 | 191 | | |
192 | 192 | | |
193 | 193 | | |
194 | | - | |
| 194 | + | |
195 | 195 | | |
196 | 196 | | |
197 | 197 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
85 | 85 | | |
86 | 86 | | |
87 | 87 | | |
| 88 | + | |
88 | 89 | | |
89 | 90 | | |
90 | 91 | | |
| |||
732 | 733 | | |
733 | 734 | | |
734 | 735 | | |
735 | | - | |
736 | | - | |
| 736 | + | |
| 737 | + | |
737 | 738 | | |
738 | 739 | | |
739 | 740 | | |
740 | 741 | | |
741 | 742 | | |
742 | 743 | | |
| 744 | + | |
| 745 | + | |
| 746 | + | |
| 747 | + | |
| 748 | + | |
| 749 | + | |
| 750 | + | |
| 751 | + | |
743 | 752 | | |
744 | 753 | | |
745 | 754 | | |
| |||
802 | 811 | | |
803 | 812 | | |
804 | 813 | | |
805 | | - | |
806 | | - | |
| 814 | + | |
| 815 | + | |
| 816 | + | |
807 | 817 | | |
808 | 818 | | |
809 | 819 | | |
810 | 820 | | |
811 | 821 | | |
| 822 | + | |
| 823 | + | |
| 824 | + | |
| 825 | + | |
| 826 | + | |
| 827 | + | |
| 828 | + | |
| 829 | + | |
812 | 830 | | |
813 | 831 | | |
814 | 832 | | |
| |||
1025 | 1043 | | |
1026 | 1044 | | |
1027 | 1045 | | |
| 1046 | + | |
1028 | 1047 | | |
1029 | 1048 | | |
1030 | 1049 | | |
| |||
1054 | 1073 | | |
1055 | 1074 | | |
1056 | 1075 | | |
1057 | | - | |
| 1076 | + | |
1058 | 1077 | | |
| 1078 | + | |
| 1079 | + | |
| 1080 | + | |
| 1081 | + | |
| 1082 | + | |
1059 | 1083 | | |
1060 | 1084 | | |
1061 | 1085 | | |
| |||
0 commit comments