refactor: merge TaskRunner failure handlers and reuse NullIfBlank
Unify the near-identical HandleFailure/MarkFailed into a single MarkFailed that always persists the failed state and never throws, and replace the inline null-if-blank checks in ListMcpTools with the existing extension. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -129,12 +129,12 @@ public sealed class TaskRunner
|
||||
}
|
||||
else
|
||||
{
|
||||
await HandleFailure(task.Id, task.Title, slot, retryResult);
|
||||
await MarkFailed(task.Id, task.Title, slot, retryResult.ErrorMarkdown, retryResult.TurnCount);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
await HandleFailure(task.Id, task.Title, slot, result);
|
||||
await MarkFailed(task.Id, task.Title, slot, result.ErrorMarkdown, result.TurnCount);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -210,7 +210,7 @@ public sealed class TaskRunner
|
||||
}
|
||||
else
|
||||
{
|
||||
await HandleFailure(taskId, task.Title, slot, result);
|
||||
await MarkFailed(taskId, task.Title, slot, result.ErrorMarkdown, result.TurnCount);
|
||||
}
|
||||
|
||||
await _broadcaster.TaskUpdated(taskId);
|
||||
@@ -331,26 +331,17 @@ public sealed class TaskRunner
|
||||
task.Id, result.TurnCount, result.TokensIn, result.TokensOut);
|
||||
}
|
||||
|
||||
private async Task HandleFailure(string taskId, string taskTitle, string slot, RunResult result)
|
||||
{
|
||||
// Intentionally does not accept a CancellationToken: this is the
|
||||
// terminal write for a failed task and must always be persisted.
|
||||
var finishedAt = DateTime.UtcNow;
|
||||
await _state.FailAsync(taskId, finishedAt, result.ErrorMarkdown, CancellationToken.None);
|
||||
await _broadcaster.WorkerLog($"Finished \"{taskTitle}\" (failed)", WorkerLogLevel.Error, DateTime.UtcNow);
|
||||
await _broadcaster.TaskFinished(slot, taskId, "failed", finishedAt);
|
||||
_logger.LogWarning("Task {TaskId} failed (turns={Turns}): {Error}", taskId, result.TurnCount, result.ErrorMarkdown);
|
||||
}
|
||||
|
||||
private async Task MarkFailed(string taskId, string taskTitle, string slot, string error)
|
||||
private async Task MarkFailed(string taskId, string taskTitle, string slot, string? error, int turnCount = 0)
|
||||
{
|
||||
// Terminal write for a failed task: never cancel (the status must always
|
||||
// be persisted) and never throw (a logging failure must not mask the error).
|
||||
try
|
||||
{
|
||||
var now = DateTime.UtcNow;
|
||||
// Terminal write — never cancel.
|
||||
await _state.FailAsync(taskId, now, error, CancellationToken.None);
|
||||
var finishedAt = DateTime.UtcNow;
|
||||
await _state.FailAsync(taskId, finishedAt, error, CancellationToken.None);
|
||||
await _broadcaster.WorkerLog($"Finished \"{taskTitle}\" (failed)", WorkerLogLevel.Error, DateTime.UtcNow);
|
||||
await _broadcaster.TaskFinished(slot, taskId, "failed", now);
|
||||
await _broadcaster.TaskFinished(slot, taskId, "failed", finishedAt);
|
||||
_logger.LogWarning("Task {TaskId} failed (turns={Turns}): {Error}", taskId, turnCount, error);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user