fix(server): remove debug logging and add error handling from review

- Remove debug log.Printf calls from handler/daemon.go and service/task.go
  that used the global log package instead of structured logging
- Remove unused truncate() helper from service/task.go
- Add error handling for EnqueueTaskForIssue in createAgentInitIssue
- Clean up verbose debug logging in daemon/daemon.go handleTask
- Add shutdown sequence comment to codex.go lifecycle goroutine

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
yushen 2026-03-24 17:48:01 +08:00
parent a9bf22955d
commit de0a983674
5 changed files with 10 additions and 56 deletions

View file

@ -247,26 +247,15 @@ func (d *Daemon) handleTask(ctx context.Context, task Task) {
_ = d.client.ReportProgress(ctx, task.ID, "Finishing task", 2, 2)
// Debug: log result details before sending to server
commentPreview := result.Comment
if len(commentPreview) > 200 {
commentPreview = commentPreview[:200] + "..."
}
d.logger.Printf("task %s result: status=%s comment_len=%d comment_preview=%q",
task.ID, result.Status, len(result.Comment), commentPreview)
switch result.Status {
case "blocked":
if err := d.client.FailTask(ctx, task.ID, result.Comment); err != nil {
d.logger.Printf("report blocked task %s failed: %v", task.ID, err)
} else {
d.logger.Printf("task %s reported as blocked to server", task.ID)
}
default:
d.logger.Printf("task %s completed status=%s", task.ID, result.Status)
if err := d.client.CompleteTask(ctx, task.ID, result.Comment); err != nil {
d.logger.Printf("complete task %s failed: %v", task.ID, err)
} else {
d.logger.Printf("task %s completed successfully on server", task.ID)
}
}
}

View file

@ -4,6 +4,7 @@ import (
"context"
"encoding/json"
"fmt"
"log"
"net/http"
"github.com/go-chi/chi/v5"
@ -285,7 +286,9 @@ func (h *Handler) createAgentInitIssue(ctx context.Context, agent db.Agent, crea
h.broadcast("issue:created", map[string]any{"issue": issueToResponse(issue)})
// Enqueue the task directly — we know the agent is assigned and status is "todo".
h.TaskService.EnqueueTaskForIssue(ctx, issue)
if _, err := h.TaskService.EnqueueTaskForIssue(ctx, issue); err != nil {
log.Printf("createAgentInitIssue: enqueue task failed for issue %s: %v", issue.Title, err)
}
}
type UpdateAgentRequest struct {

View file

@ -3,7 +3,6 @@ package handler
import (
"encoding/json"
"fmt"
"log"
"net/http"
"strings"
@ -207,17 +206,13 @@ func (h *Handler) CompleteTask(w http.ResponseWriter, r *http.Request) {
return
}
log.Printf("[Handler.CompleteTask] task=%s output_len=%d", taskID, len(req.Output))
result, _ := json.Marshal(req)
task, err := h.TaskService.CompleteTask(r.Context(), parseUUID(taskID), result)
if err != nil {
log.Printf("[Handler.CompleteTask] task=%s error: %v", taskID, err)
writeError(w, http.StatusBadRequest, err.Error())
return
}
log.Printf("[Handler.CompleteTask] task=%s completed, issue status synced", taskID)
writeJSON(w, http.StatusOK, taskToResponse(*task))
}

View file

@ -5,7 +5,6 @@ import (
"encoding/json"
"errors"
"fmt"
"log"
"github.com/jackc/pgx/v5"
"github.com/jackc/pgx/v5/pgtype"
@ -112,14 +111,6 @@ func (s *TaskService) ClaimTaskForRuntime(ctx context.Context, runtimeID pgtype.
return nil, fmt.Errorf("list pending tasks: %w", err)
}
if len(tasks) > 0 {
log.Printf("[ClaimTaskForRuntime] runtime=%s found %d pending tasks", util.UUIDToString(runtimeID), len(tasks))
for _, t := range tasks {
log.Printf("[ClaimTaskForRuntime] task=%s agent=%s status=%s",
util.UUIDToString(t.ID), util.UUIDToString(t.AgentID), t.Status)
}
}
triedAgents := map[string]struct{}{}
for _, candidate := range tasks {
agentKey := util.UUIDToString(candidate.AgentID)
@ -130,16 +121,11 @@ func (s *TaskService) ClaimTaskForRuntime(ctx context.Context, runtimeID pgtype.
task, err := s.ClaimTask(ctx, candidate.AgentID)
if err != nil {
log.Printf("[ClaimTaskForRuntime] ClaimTask for agent %s failed: %v", agentKey, err)
return nil, err
}
if task != nil && task.RuntimeID == runtimeID {
return task, nil
}
if task != nil {
log.Printf("[ClaimTaskForRuntime] task %s runtime mismatch: task.RuntimeID=%s != requested=%s",
util.UUIDToString(task.ID), util.UUIDToString(task.RuntimeID), util.UUIDToString(runtimeID))
}
}
return nil, nil
@ -166,43 +152,28 @@ func (s *TaskService) StartTask(ctx context.Context, taskID pgtype.UUID) (*db.Ag
// CompleteTask marks a task as completed and syncs issue/agent status.
func (s *TaskService) CompleteTask(ctx context.Context, taskID pgtype.UUID, result []byte) (*db.AgentTaskQueue, error) {
log.Printf("[CompleteTask] task=%s result_len=%d result_preview=%s",
util.UUIDToString(taskID), len(result), truncate(string(result), 200))
task, err := s.Queries.CompleteAgentTask(ctx, db.CompleteAgentTaskParams{
ID: taskID,
Result: result,
})
if err != nil {
log.Printf("[CompleteTask] CompleteAgentTask failed: %v (task may not be in 'running' state)", err)
return nil, fmt.Errorf("complete task: %w", err)
}
log.Printf("[CompleteTask] task %s marked completed, issue=%s agent=%s",
util.UUIDToString(task.ID), util.UUIDToString(task.IssueID), util.UUIDToString(task.AgentID))
// Sync issue → in_review
issue, issueErr := s.Queries.UpdateIssueStatus(ctx, db.UpdateIssueStatusParams{
ID: task.IssueID,
Status: "in_review",
})
if issueErr != nil {
log.Printf("[CompleteTask] UpdateIssueStatus to in_review failed: %v", issueErr)
} else {
log.Printf("[CompleteTask] issue %s status updated to in_review", util.UUIDToString(issue.ID))
if issueErr == nil {
s.broadcastIssueUpdated(issue)
}
var payload protocol.TaskCompletedPayload
if err := json.Unmarshal(result, &payload); err == nil {
log.Printf("[CompleteTask] parsed payload: output_len=%d", len(payload.Output))
if payload.Output != "" {
s.createAgentComment(ctx, task.IssueID, task.AgentID, payload.Output, "comment")
log.Printf("[CompleteTask] created agent comment for issue %s", util.UUIDToString(task.IssueID))
} else {
log.Printf("[CompleteTask] payload.Output is empty, skipping comment")
}
} else {
log.Printf("[CompleteTask] failed to unmarshal result into TaskCompletedPayload: %v", err)
}
if issueErr == nil {
@ -491,13 +462,6 @@ func inboxToMap(item db.InboxItem) map[string]any {
}
}
func truncate(s string, n int) string {
if len(s) <= n {
return s
}
return s[:n] + "..."
}
// agentToMap builds a simple map for broadcasting agent status updates.
func agentToMap(a db.Agent) map[string]any {
var rc any

View file

@ -104,7 +104,10 @@ func (b *codexBackend) Execute(ctx context.Context, prompt string, opts ExecOpti
c.closeAllPending(fmt.Errorf("codex process exited"))
}()
// Drive the session lifecycle in a goroutine
// Drive the session lifecycle in a goroutine.
// Shutdown sequence: lifecycle goroutine closes stdin + cancels context →
// codex process exits → reader goroutine's scanner.Scan() returns false →
// readerDone closes → lifecycle goroutine collects final output and sends Result.
go func() {
defer cancel()
defer close(msgCh)