diff --git a/cmd/workflow/logs/logs.go b/cmd/workflow/logs/logs.go index cd20149e..87bb98b6 100644 --- a/cmd/workflow/logs/logs.go +++ b/cmd/workflow/logs/logs.go @@ -289,7 +289,12 @@ func (h *handler) printErrors(ctx context.Context, client *graphqlclient.Client, if ev.Status == "failure" && len(ev.Errors) > 0 { errMsg := ev.Errors[0].Error if len(errMsg) > 120 { - errMsg = errMsg[:120] + "..." + tail := errMsg[len(errMsg)-len(errMsg)*2/5:] // last 40% + head := 120 - len(tail) - 3 + if head < 0 { + head = 0 + } + errMsg = errMsg[:head] + "..." + tail } fmt.Printf(" -> %s: %s\n", ev.CapabilityID, errMsg) } diff --git a/cmd/workflow/logs/logs_test.go b/cmd/workflow/logs/logs_test.go index bf273a1a..c87ba2fd 100644 --- a/cmd/workflow/logs/logs_test.go +++ b/cmd/workflow/logs/logs_test.go @@ -180,6 +180,44 @@ func TestExecute(t *testing.T) { assert.Greater(t, failureIdx, successIdx, "oldest execution should appear first") }) + t.Run("long error is truncated keeping tail", func(t *testing.T) { + longErr := "failed to execute enclave request. enclave ID: abc123, error: attestation validation failed for ExecuteBatch: expected PCR0 deadbeef, got cafebabe" + ts := newMockGraphQL(t, mockConfig{ + workflows: []map[string]any{ + {"uuid": "wf-1", "name": "test-workflow", "status": "ACTIVE"}, + }, + executions: []map[string]any{ + { + "uuid": "exec-1", + "status": "FAILURE", + "startedAt": "2026-02-12T16:00:00Z", + "finishedAt": "2026-02-12T16:00:01Z", + }, + }, + events: []map[string]any{ + { + "capabilityID": "confidential-http@1.0.0", + "status": "failure", + "errors": []map[string]any{{"error": longErr, "count": 1}}, + }, + }, + }) + defer ts.Close() + + output := captureStdout(t, func() { + h := newTestHandler(ts.URL, "test-workflow", false, 10) + err := h.Execute(context.Background()) + require.NoError(t, err) + }) + + // Head (beginning) should be present + assert.Contains(t, output, "failed to execute enclave") + // Tail (last 40%) should survive truncation + assert.Contains(t, output, "expected PCR0 deadbeef, got cafebabe") + // Middle should be elided + assert.Contains(t, output, "...") + }) + t.Run("workflow not found", func(t *testing.T) { ts := newMockGraphQL(t, mockConfig{}) defer ts.Close()