From 5ec4eb5592d0ca6fdebdb9db7014900879c0a63a Mon Sep 17 00:00:00 2001 From: Ben Sima Date: Tue, 23 Dec 2025 09:27:51 -0500 Subject: Omni/Ci: fix extractErrorMessage function MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Improve error message extraction to preserve meaningful error information instead of filtering everything out. Fixed fallback logic and ANSI escape sequence handling to prevent "Unknown error" messages in CI git notes. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude --- Omni/Ci.hs | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/Omni/Ci.hs b/Omni/Ci.hs index bc84aae..09fe9d8 100755 --- a/Omni/Ci.hs +++ b/Omni/Ci.hs @@ -208,16 +208,19 @@ getCoderoot = do -- | Extract meaningful error messages from tool output, filtering out progress/status lines extractErrorMessage :: Text -> Text extractErrorMessage output = - let errorLines = - Text.lines output - |> map stripAnsiEscapes -- Remove ANSI escape sequences - |> filter isErrorLine - |> take 5 -- Limit to first 5 error lines - cleaned = + let cleanedLines = Text.lines output |> map stripAnsiEscapes |> filter (not <. Text.null) + -- First try to find explicit error lines + errorLines = cleanedLines |> filter isErrorLine |> take 5 + -- If no explicit errors, take last few non-empty lines (likely contain the issue) + fallbackLines = if null errorLines - then ["Unknown error (no error lines found)"] - else errorLines - in Text.unlines cleaned + then cleanedLines |> reverse |> take 3 |> reverse + else [] + finalLines + | null errorLines && null fallbackLines = ["Build failed (exit code non-zero, no error output captured)"] + | null errorLines = fallbackLines + | otherwise = errorLines + in Text.unlines finalLines where isErrorLine line = let stripped = Text.strip line @@ -230,12 +233,16 @@ extractErrorMessage output = `Text.isInfixOf` stripped || "ERROR:" `Text.isInfixOf` stripped + || "failed" + `Text.isInfixOf` stripped ) && not ("warning:" `Text.isInfixOf` stripped) -- Exclude warnings + && not ("[" `Text.isPrefixOf` stripped) -- Skip progress indicators like [1/10] -- Remove ANSI escape sequences including carriage returns stripAnsiEscapes line = line |> Text.replace "\r" "" -- Remove carriage returns |> Text.replace "\ESC[" "" -- Remove ANSI escape start + |> Text.replace "\x1b[" "" -- Alternative ANSI escape sequence |> Text.filter (\c -> c >= ' ' || c == '\t') -- Keep only printable chars and tabs -- cgit v1.2.3