Extract relevant error snippets from process output. Searches for lines containing actual error messages (not compiler flags like -Werror) and extracts context around the first few occurrences. Always includes the tail of the output to ensure failure summaries are visible.
(accumulated_output: list[str], context_lines: int = 5)
| 176 | |
| 177 | |
| 178 | def extract_error_snippet(accumulated_output: list[str], context_lines: int = 5) -> str: |
| 179 | """ |
| 180 | Extract relevant error snippets from process output. |
| 181 | |
| 182 | Searches for lines containing actual error messages (not compiler flags |
| 183 | like -Werror) and extracts context around the first few occurrences. |
| 184 | Always includes the tail of the output to ensure failure summaries are |
| 185 | visible. |
| 186 | |
| 187 | Args: |
| 188 | accumulated_output: List of output lines from the process |
| 189 | context_lines: Number of lines to capture before/after each error line (default: 5) |
| 190 | |
| 191 | Returns: |
| 192 | Formatted string containing error snippets with tail context |
| 193 | """ |
| 194 | if not accumulated_output: |
| 195 | return "No output captured" |
| 196 | |
| 197 | error_snippets: list[str] = [] |
| 198 | |
| 199 | # Find all lines that contain real error indicators |
| 200 | error_line_indices: list[int] = [] |
| 201 | for i, line in enumerate(accumulated_output): |
| 202 | if _is_real_error_line(line): |
| 203 | error_line_indices.append(i) |
| 204 | |
| 205 | # Always capture tail of output (last 30 lines) for failure summaries |
| 206 | tail_count = 30 |
| 207 | tail_start = max(0, len(accumulated_output) - tail_count) |
| 208 | |
| 209 | if not error_line_indices: |
| 210 | # No specific errors found, return tail which often has useful info |
| 211 | max_lines = min(tail_count, len(accumulated_output)) |
| 212 | return ( |
| 213 | "No specific error lines found. Last " |
| 214 | + str(max_lines) |
| 215 | + " lines:\n" |
| 216 | + "\n".join(accumulated_output[-max_lines:]) |
| 217 | ) |
| 218 | |
| 219 | # Extract context around first 10 errors |
| 220 | max_errors_to_show = 10 |
| 221 | shown_lines: set[int] = set() |
| 222 | |
| 223 | for error_idx in error_line_indices[:max_errors_to_show]: |
| 224 | start_idx = max(0, error_idx - context_lines) |
| 225 | end_idx = min(len(accumulated_output), error_idx + context_lines + 1) |
| 226 | |
| 227 | snippet_lines: list[str] = [] |
| 228 | for j in range(start_idx, end_idx): |
| 229 | if j not in shown_lines: |
| 230 | line_marker = "➤ " if j == error_idx else " " |
| 231 | snippet_lines.append(f"{line_marker}{accumulated_output[j]}") |
| 232 | shown_lines.add(j) |
| 233 | |
| 234 | if snippet_lines: |
| 235 | error_snippets.append("\n".join(snippet_lines)) |
no test coverage detected