fix(ui): silent no-ops raise ErrorReported instead of swallowing failures (UX-Audit #1)

Stop/Enqueue/Dequeue/Reset&Retry (DetailsIslandViewModel), status/cancel/reject
commands (TasksIslandViewModel), Mission Control's drag-enqueue and queue
refresh, and "Open findings folder" (ListsIslandViewModel) used to catch {}
or silently return on a blocked precondition. They now report through the
existing ErrorReported -> FlashFooterError path, with new en/de locale keys
and Ui.Tests covering each converted command.
This commit is contained in:
mika kuns
2026-08-21 09:13:00 +02:00
parent fdd0e1e56a
commit 99bb5be5da
10 changed files with 468 additions and 20 deletions
@@ -1129,9 +1129,13 @@ public sealed partial class DetailsIslandViewModel : ViewModelBase, IDisposable
private async System.Threading.Tasks.Task StopAsync()
{
if (Task == null || !IsRunning) return;
if (!_worker.IsConnected) return;
if (!_worker.IsConnected)
{
ErrorReported?.Invoke(Loc.T("vm.detailsIsland.stopOffline"));
return;
}
try { await _worker.CancelTaskAsync(Task.Id); }
catch { /* offline */ }
catch (Exception ex) { ErrorReported?.Invoke(Loc.T("vm.detailsIsland.stopFailed", ex.Message)); }
}
[RelayCommand(CanExecute = nameof(CanEnqueue))]
@@ -1144,7 +1148,7 @@ public sealed partial class DetailsIslandViewModel : ViewModelBase, IDisposable
AgentState = "queued";
ReportBaseDirty(baseDirty);
}
catch { /* offline */ }
catch (Exception ex) { ErrorReported?.Invoke(Loc.T("vm.detailsIsland.enqueueFailed", ex.Message)); }
}
private void ReportBaseDirty(BaseDirtyWarningDto? warning)
@@ -1167,7 +1171,7 @@ public sealed partial class DetailsIslandViewModel : ViewModelBase, IDisposable
await _worker.SetTaskStatusAsync(Task.Id, ClaudeDo.Data.Models.TaskStatus.Idle);
AgentState = "idle";
}
catch { /* offline */ }
catch (Exception ex) { ErrorReported?.Invoke(Loc.T("vm.detailsIsland.dequeueFailed", ex.Message)); }
}
private bool CanDequeue() =>
@@ -1223,7 +1227,7 @@ public sealed partial class DetailsIslandViewModel : ViewModelBase, IDisposable
AgentState = "queued";
ReportBaseDirty(baseDirty);
}
catch { /* offline */ }
catch (Exception ex) { ErrorReported?.Invoke(Loc.T("vm.detailsIsland.resetAndRetryFailed", ex.Message)); }
}
// Reset & Retry discards the branch/uncommitted work and queues an autonomous run into the