From 474238cfc592ac56ca9b75d9b0a4c7bea3ff84ee Mon Sep 17 00:00:00 2001 From: temp Date: Mon, 24 Aug 2026 14:53:02 +0800 Subject: [PATCH] fix: distinguish model original errors --- internal/multiagent/eino_run_error_handler.go | 27 ++++++++++++++----- .../multiagent/eino_run_error_handler_test.go | 22 ++++++++++++--- 2 files changed, 39 insertions(+), 10 deletions(-) diff --git a/internal/multiagent/eino_run_error_handler.go b/internal/multiagent/eino_run_error_handler.go index 7e26c077..94575cd9 100644 --- a/internal/multiagent/eino_run_error_handler.go +++ b/internal/multiagent/eino_run_error_handler.go @@ -107,6 +107,14 @@ func (h *einoRunErrorHandler) emitError(err error, kind string) { if userErr.rawLastError != "" { data["lastError"] = userErr.rawLastError } + if userErr.technicalError != "" { + data["technicalError"] = userErr.technicalError + } + if userErr.hasModelOriginalError { + data["modelOriginalError"] = userErr.rawLastError + } else if userErr.retryExhausted { + data["hasModelOriginalError"] = false + } message := err.Error() if userErr.message != "" { message = userErr.message @@ -115,12 +123,14 @@ func (h *einoRunErrorHandler) emitError(err error, kind string) { } type einoRunUserError struct { - message string - kind string - summary string - rawLastError string - retryExhausted bool - totalRetries int + message string + kind string + summary string + rawLastError string + technicalError string + retryExhausted bool + totalRetries int + hasModelOriginalError bool } func einoUserFacingRunError(err error) einoRunUserError { @@ -144,7 +154,9 @@ func einoUserFacingRunError(err error) einoRunUserError { out.rawLastError = strings.TrimSpace(lastErr.Error()) if isEinoShouldRetryOutputRejected(lastErr) { out.kind = "model_output_rejected" - out.message = formatEinoRetryExhaustedMessage(out.rawLastError, retryErr.TotalRetries) + out.summary = "模型未返回原始错误;输出被重试策略拒绝。" + out.technicalError = out.rawLastError + out.message = formatEinoRetryExhaustedMessage(out.summary, retryErr.TotalRetries) return out } kind, summary := einoTransientRunErrorUserDetail(lastErr) @@ -156,6 +168,7 @@ func einoUserFacingRunError(err error) einoRunUserError { } out.kind = kind out.summary = summary + out.hasModelOriginalError = out.rawLastError != "" out.message = formatEinoRetryExhaustedMessage(summary, retryErr.TotalRetries) return out } diff --git a/internal/multiagent/eino_run_error_handler_test.go b/internal/multiagent/eino_run_error_handler_test.go index fd200777..f25865e5 100644 --- a/internal/multiagent/eino_run_error_handler_test.go +++ b/internal/multiagent/eino_run_error_handler_test.go @@ -84,14 +84,18 @@ func TestEinoRunErrorHandlerRetryExhaustedEmptyOutputProgress(t *testing.T) { t.Fatalf("err = %v", got) } if !strings.Contains(message, "模型调用重试已耗尽") || - !strings.Contains(message, "model output rejected by ShouldRetry at attempt 5") { + !strings.Contains(message, "模型未返回原始错误;输出被重试策略拒绝。") || + strings.Contains(message, "model output rejected by ShouldRetry at attempt 5") { t.Fatalf("message = %q", message) } if data["errorKind"] != "model_output_rejected" { t.Fatalf("errorKind = %#v", data["errorKind"]) } - if _, ok := data["errorSummary"]; ok { - t.Fatalf("errorSummary should not infer a reason, got %#v", data["errorSummary"]) + if data["errorSummary"] != "模型未返回原始错误;输出被重试策略拒绝。" { + t.Fatalf("errorSummary = %#v", data["errorSummary"]) + } + if data["hasModelOriginalError"] != false { + t.Fatalf("hasModelOriginalError = %#v", data["hasModelOriginalError"]) } if data["retryExhausted"] != true || data["totalRetries"] != 4 { t.Fatalf("retry metadata = %#v", data) @@ -99,6 +103,12 @@ func TestEinoRunErrorHandlerRetryExhaustedEmptyOutputProgress(t *testing.T) { if data["lastError"] != "model output rejected by ShouldRetry at attempt 5" { t.Fatalf("lastError = %#v", data["lastError"]) } + if data["technicalError"] != "model output rejected by ShouldRetry at attempt 5" { + t.Fatalf("technicalError = %#v", data["technicalError"]) + } + if _, ok := data["modelOriginalError"]; ok { + t.Fatalf("modelOriginalError should be absent for ShouldRetry rejection, got %#v", data["modelOriginalError"]) + } if data["error"] != err.Error() { t.Fatalf("raw error = %#v, want %#v", data["error"], err.Error()) } @@ -137,6 +147,12 @@ func TestEinoRunErrorHandlerRetryExhaustedOriginalErrorProgress(t *testing.T) { if data["lastError"] != "HTTP 429 Too Many Requests" { t.Fatalf("lastError = %#v", data["lastError"]) } + if data["modelOriginalError"] != "HTTP 429 Too Many Requests" { + t.Fatalf("modelOriginalError = %#v", data["modelOriginalError"]) + } + if _, ok := data["hasModelOriginalError"]; ok { + t.Fatalf("hasModelOriginalError should be absent when original error is present, got %#v", data["hasModelOriginalError"]) + } } func TestEinoRunErrorHandlerIterationLimitProgress(t *testing.T) {