mirror of
https://github.com/go-task/task.git
synced 2025-11-23 22:24:45 +02:00
fix: make task failure errors include stack of running tasks (#2286)
Previously if a task was run as a dependency of another task,
the error message simply reported something like:
exit status 1
It is desirable instead to name the root task and all child tasks in the tree
to the failing task.
After this PR, the error message will read:
task: Failed to run task "root": task: Failed to run task "failing-task": exit status 1
This commit is contained in:
@@ -54,6 +54,10 @@ func (err *TaskRunError) TaskExitCode() int {
|
|||||||
return err.Code()
|
return err.Code()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (err *TaskRunError) Unwrap() error {
|
||||||
|
return err.Err
|
||||||
|
}
|
||||||
|
|
||||||
// TaskInternalError when the user attempts to invoke a task that is internal.
|
// TaskInternalError when the user attempts to invoke a task that is internal.
|
||||||
type TaskInternalError struct {
|
type TaskInternalError struct {
|
||||||
TaskName string
|
TaskName string
|
||||||
|
|||||||
@@ -665,6 +665,15 @@ func TestLabel(t *testing.T) {
|
|||||||
),
|
),
|
||||||
WithTask("foo"),
|
WithTask("foo"),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
NewExecutorTest(t,
|
||||||
|
WithName("label in error"),
|
||||||
|
WithExecutorOptions(
|
||||||
|
task.WithDir("testdata/label_error"),
|
||||||
|
),
|
||||||
|
WithTask("foo"),
|
||||||
|
WithRunError(),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestPromptInSummary(t *testing.T) {
|
func TestPromptInSummary(t *testing.T) {
|
||||||
|
|||||||
14
task.go
14
task.go
@@ -150,7 +150,7 @@ func (e *Executor) RunTask(ctx context.Context, call *Call) error {
|
|||||||
release := e.acquireConcurrencyLimit()
|
release := e.acquireConcurrencyLimit()
|
||||||
defer release()
|
defer release()
|
||||||
|
|
||||||
return e.startExecution(ctx, t, func(ctx context.Context) error {
|
if err = e.startExecution(ctx, t, func(ctx context.Context) error {
|
||||||
e.Logger.VerboseErrf(logger.Magenta, "task: %q started\n", call.Task)
|
e.Logger.VerboseErrf(logger.Magenta, "task: %q started\n", call.Task)
|
||||||
if err := e.runDeps(ctx, t); err != nil {
|
if err := e.runDeps(ctx, t); err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -228,16 +228,16 @@ func (e *Executor) RunTask(ctx context.Context, call *Call) error {
|
|||||||
deferredExitCode = uint8(exitCode)
|
deferredExitCode = uint8(exitCode)
|
||||||
}
|
}
|
||||||
|
|
||||||
if call.Indirect {
|
return err
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return &errors.TaskRunError{TaskName: t.Task, Err: err}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
e.Logger.VerboseErrf(logger.Magenta, "task: %q finished\n", call.Task)
|
e.Logger.VerboseErrf(logger.Magenta, "task: %q finished\n", call.Task)
|
||||||
return nil
|
return nil
|
||||||
})
|
}); err != nil {
|
||||||
|
return &errors.TaskRunError{TaskName: t.Name(), Err: err}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Executor) mkdir(t *ast.Task) error {
|
func (e *Executor) mkdir(t *ast.Task) error {
|
||||||
|
|||||||
@@ -569,7 +569,9 @@ func TestCyclicDep(t *testing.T) {
|
|||||||
task.WithStderr(io.Discard),
|
task.WithStderr(io.Discard),
|
||||||
)
|
)
|
||||||
require.NoError(t, e.Setup())
|
require.NoError(t, e.Setup())
|
||||||
assert.IsType(t, &errors.TaskCalledTooManyTimesError{}, e.Run(t.Context(), &task.Call{Task: "task-1"}))
|
err := e.Run(t.Context(), &task.Call{Task: "task-1"})
|
||||||
|
var taskCalledTooManyTimesError *errors.TaskCalledTooManyTimesError
|
||||||
|
assert.ErrorAs(t, err, &taskCalledTooManyTimesError)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestTaskVersion(t *testing.T) {
|
func TestTaskVersion(t *testing.T) {
|
||||||
|
|||||||
7
testdata/label_error/Taskfile.yml
vendored
Normal file
7
testdata/label_error/Taskfile.yml
vendored
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
version: '3'
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
foo:
|
||||||
|
label: "foobar"
|
||||||
|
cmds:
|
||||||
|
- "false"
|
||||||
1
testdata/label_error/testdata/TestLabel-label_in_error-err-run.golden
vendored
Normal file
1
testdata/label_error/testdata/TestLabel-label_in_error-err-run.golden
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
task: Failed to run task "foobar": exit status 1
|
||||||
1
testdata/label_error/testdata/TestLabel-label_in_error.golden
vendored
Normal file
1
testdata/label_error/testdata/TestLabel-label_in_error.golden
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
task: [foobar] false
|
||||||
@@ -1 +1 @@
|
|||||||
task: precondition not met
|
task: Failed to run task "impossible": task: precondition not met
|
||||||
@@ -1 +1 @@
|
|||||||
task: Failed to run task "executes_failing_task_as_cmd": task: precondition not met
|
task: Failed to run task "executes_failing_task_as_cmd": task: Failed to run task "impossible": task: precondition not met
|
||||||
@@ -1 +1 @@
|
|||||||
task: precondition not met
|
task: Failed to run task "depends_on_impossible": task: Failed to run task "impossible": task: precondition not met
|
||||||
@@ -1 +1 @@
|
|||||||
task: Task "foo" cancelled by user
|
task: Failed to run task "foo": task: Task "foo" cancelled by user
|
||||||
@@ -1 +1 @@
|
|||||||
task: Task "foo" cancelled by user
|
task: Failed to run task "foo": task: Task "foo" cancelled by user
|
||||||
@@ -1 +1 @@
|
|||||||
task: Task "foo" cancelled by user
|
task: Failed to run task "foo": task: Task "foo" cancelled by user
|
||||||
@@ -1 +1 @@
|
|||||||
task: Task "foo" cancelled by user
|
task: Failed to run task "foo": task: Task "foo" cancelled by user
|
||||||
Reference in New Issue
Block a user