From 03caf18985778db4f84cfedd05c37e5f86ce2c7e Mon Sep 17 00:00:00 2001 From: Tejaswi Nadahalli Date: Thu, 12 Feb 2026 17:53:46 +0100 Subject: [PATCH 1/2] Truncate long errors keeping the diagnostic tail Drop the first 40% of long error messages (>80 chars) since the useful diagnostic info (e.g. PCR mismatches) sits at the end, after layers of generic wrapping. --- cmd/workflow/logs/logs.go | 5 +++-- cmd/workflow/logs/logs_test.go | 37 ++++++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+), 2 deletions(-) diff --git a/cmd/workflow/logs/logs.go b/cmd/workflow/logs/logs.go index cd20149e..2386b7a3 100644 --- a/cmd/workflow/logs/logs.go +++ b/cmd/workflow/logs/logs.go @@ -288,8 +288,9 @@ func (h *handler) printErrors(ctx context.Context, client *graphqlclient.Client, for _, ev := range resp.WorkflowExecutionEvents.Data { if ev.Status == "failure" && len(ev.Errors) > 0 { errMsg := ev.Errors[0].Error - if len(errMsg) > 120 { - errMsg = errMsg[:120] + "..." + if len(errMsg) > 80 { + start := len(errMsg) * 2 / 5 // drop first 40%, keep the diagnostic tail + errMsg = "..." + errMsg[start:] } 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 b3d8a2ef..8ed11f1e 100644 --- a/cmd/workflow/logs/logs_test.go +++ b/cmd/workflow/logs/logs_test.go @@ -180,6 +180,43 @@ 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) + }) + + // The diagnostic tail should survive truncation + assert.Contains(t, output, "expected PCR0 deadbeef, got cafebabe") + // The generic prefix should be dropped + assert.NotContains(t, output, "failed to execute enclave request") + assert.Contains(t, output, "...") + }) + t.Run("workflow not found", func(t *testing.T) { ts := newMockGraphQL(t, mockConfig{}) defer ts.Close() From c671cc6296ba656f99dce9bad8fa58141d70290d Mon Sep 17 00:00:00 2001 From: Tejaswi Nadahalli Date: Thu, 12 Feb 2026 17:55:21 +0100 Subject: [PATCH 2/2] Truncate long errors keeping head and diagnostic tail For errors >120 chars, show the beginning + "..." + last 40%. Nested error wrapping puts the useful diagnostic (e.g. PCR mismatches) at the end; this keeps both ends visible. --- cmd/workflow/logs/logs.go | 10 +++++++--- cmd/workflow/logs/logs_test.go | 7 ++++--- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/cmd/workflow/logs/logs.go b/cmd/workflow/logs/logs.go index 2386b7a3..87bb98b6 100644 --- a/cmd/workflow/logs/logs.go +++ b/cmd/workflow/logs/logs.go @@ -288,9 +288,13 @@ func (h *handler) printErrors(ctx context.Context, client *graphqlclient.Client, for _, ev := range resp.WorkflowExecutionEvents.Data { if ev.Status == "failure" && len(ev.Errors) > 0 { errMsg := ev.Errors[0].Error - if len(errMsg) > 80 { - start := len(errMsg) * 2 / 5 // drop first 40%, keep the diagnostic tail - errMsg = "..." + errMsg[start:] + if len(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 8ed11f1e..9b22048b 100644 --- a/cmd/workflow/logs/logs_test.go +++ b/cmd/workflow/logs/logs_test.go @@ -210,10 +210,11 @@ func TestExecute(t *testing.T) { require.NoError(t, err) }) - // The diagnostic tail should survive truncation + // 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") - // The generic prefix should be dropped - assert.NotContains(t, output, "failed to execute enclave request") + // Middle should be elided assert.Contains(t, output, "...") })