diff options
| author | Paul Buetow <paul@buetow.org> | 2026-05-29 17:39:29 +0300 |
|---|---|---|
| committer | Paul Buetow <paul@buetow.org> | 2026-05-29 17:39:29 +0300 |
| commit | 5b49734f3e2bba38e689f274d39e5ff3b52f529d (patch) | |
| tree | f34085421da47a11761412e315fa78ac94cfb154 /internal/askcli | |
| parent | b3cf20116d403e4437a2aaa726bdcf188109cf9f (diff) | |
askcli: keep ask add successful when alias assignment fails
Diffstat (limited to 'internal/askcli')
| -rw-r--r-- | internal/askcli/command_add.go | 13 | ||||
| -rw-r--r-- | internal/askcli/command_info_add_test.go | 21 |
2 files changed, 24 insertions, 10 deletions
diff --git a/internal/askcli/command_add.go b/internal/askcli/command_add.go index b94fe89..096046d 100644 --- a/internal/askcli/command_add.go +++ b/internal/askcli/command_add.go @@ -45,10 +45,15 @@ func (d *Dispatcher) handleAdd(ctx context.Context, args []string, stdout, stder _, _ = io.WriteString(stderr, "error: could not parse UUID from task creation output\n") return 1, nil } - aliases, err := ensureTaskAliasesForUUIDs([]string{uuid}) - if err != nil { - fmt.Fprintf(stderr, "error: failed to assign task alias: %v\n", err) - return 1, nil + // The task is already created in Taskwarrior. If alias assignment fails + // (e.g. cache lock timeout, validation error, disk full), surface the + // problem as a warning on stderr but still report success on stdout with + // exit 0 so the user does not retry and create a duplicate task. The + // displayed identifier falls back to the UUID when no alias is available. + aliases, aliasErr := ensureTaskAliasesForUUIDs([]string{uuid}) + if aliasErr != nil { + fmt.Fprintf(stderr, "warning: failed to assign task alias: %v\n", aliasErr) + aliases = nil } _, _ = io.WriteString(stdout, FormatCreatedTask(displayTaskAlias(uuid, aliases))) return 0, nil diff --git a/internal/askcli/command_info_add_test.go b/internal/askcli/command_info_add_test.go index b6f0bd0..b918518 100644 --- a/internal/askcli/command_info_add_test.go +++ b/internal/askcli/command_info_add_test.go @@ -342,6 +342,12 @@ func TestHandleAdd_Success(t *testing.T) { } } +// TestHandleAdd_AliasAssignmentFailure verifies that when alias assignment +// fails after the task is already created in Taskwarrior, the command still +// exits 0 and prints "created task <uuid>" on stdout (with the UUID as +// fallback identifier), while emitting the failure as a warning on stderr. +// This prevents the previous bug where the user saw exit 1 and retried, +// creating duplicate tasks. func TestHandleAdd_AliasAssignmentFailure(t *testing.T) { oldRoot := taskAliasCacheRoot taskAliasCacheRoot = func() (string, error) { return "", io.ErrUnexpectedEOF } @@ -354,14 +360,17 @@ func TestHandleAdd_AliasAssignmentFailure(t *testing.T) { var stdout, stderr bytes.Buffer code, _ := d.Dispatch(context.Background(), []string{"add", "New task description"}, nil, &stdout, &stderr) - if code != 1 { - t.Fatalf("add code = %d, want 1", code) + if code != 0 { + t.Fatalf("add code = %d, want 0 (task was created, alias failure is non-fatal)", code) + } + if got := strings.TrimSpace(stdout.String()); got != "created task abc-123-def" { + t.Fatalf("stdout = %q, want \"created task abc-123-def\" (UUID fallback)", stdout.String()) } - if stdout.Len() != 0 { - t.Fatalf("stdout = %q, want empty output on alias assignment failure", stdout.String()) + if !strings.Contains(stderr.String(), "warning: failed to assign task alias") { + t.Fatalf("stderr = %q, want warning about alias assignment failure", stderr.String()) } - if !strings.Contains(stderr.String(), "failed to assign task alias") { - t.Fatalf("stderr = %q, want alias assignment failure", stderr.String()) + if strings.Contains(stderr.String(), "error: failed to assign task alias") { + t.Fatalf("stderr = %q, alias failure should be a warning, not an error", stderr.String()) } } |
