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
@@ -1136,7 +1136,7 @@ public sealed partial class TasksIslandViewModel : ViewModelBase, IDisposable
var baseDirty = await _worker.SetTaskStatusAsync(row.Id, status);
ReportBaseDirty(baseDirty);
}
catch { /* offline; broadcast won't fire */ }
catch (Exception ex) { ErrorReported?.Invoke(Loc.T("vm.tasksIsland.setStatusFailed", ex.Message)); }
}
private void ReportBaseDirty(BaseDirtyWarningDto? warning)
@@ -1227,7 +1227,7 @@ public sealed partial class TasksIslandViewModel : ViewModelBase, IDisposable
{
if (row is null || !row.IsRunning || _worker is null) return;
try { await _worker.CancelTaskAsync(row.Id); }
catch { /* worker offline; the broadcast will reconcile when it returns */ }
catch (Exception ex) { ErrorReported?.Invoke(Loc.T("vm.tasksIsland.cancelFailed", ex.Message)); }
}
// ── Review actions (visible when a task is WaitingForReview) ─────────────
@@ -1247,7 +1247,7 @@ public sealed partial class TasksIslandViewModel : ViewModelBase, IDisposable
if (!row.IsWaitingForReview || _worker is null) return;
if (string.IsNullOrWhiteSpace(feedback)) return;
try { await _worker.RejectReviewToQueueAsync(row.Id, feedback); }
catch { /* offline; broadcast reconciles on return */ }
catch (Exception ex) { ErrorReported?.Invoke(Loc.T("vm.tasksIsland.rejectToQueueFailed", ex.Message)); }
}
[RelayCommand]
@@ -1255,7 +1255,7 @@ public sealed partial class TasksIslandViewModel : ViewModelBase, IDisposable
{
if (row is null || !row.IsWaitingForReview || _worker is null) return;
try { await _worker.RejectReviewToIdleAsync(row.Id); }
catch { /* offline; broadcast reconciles on return */ }
catch (Exception ex) { ErrorReported?.Invoke(Loc.T("vm.tasksIsland.rejectToIdleFailed", ex.Message)); }
}
[RelayCommand]