Spaces:
Sleeping
Sleeping
File size: 3,405 Bytes
9bed109 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 | from __future__ import annotations
import re
from dataclasses import dataclass
@dataclass
class ParsedError:
error_type: (
str # "AttributeError", "TypeError", "ImportError", "NameError", "SyntaxError", etc.
)
symbol: str | None # Extracted symbol: "play_text", "ShowCreation", etc.
invalid_arg: str | None # For TypeError: what arg was wrong
traceback_tail: str # Last few lines of traceback
line_number: int | None # Extracted from "line XX" in traceback
raw_message: str
def parse_render_error(error_logs: str) -> ParsedError:
"""Extract structured error info from Manim render logs."""
# 1. Get the last line (the error message itself)
lines = [line.strip() for line in error_logs.strip().split("\n") if line.strip()]
if not lines:
return ParsedError("UnknownError", None, None, "", None, error_logs)
last_line = lines[-1]
# 2. Extract Traceback Tail
traceback_tail = "\n".join(lines[-5:]) if len(lines) >= 5 else "\n".join(lines)
# 3. Extract Line Number
line_match = re.search(r'File ".*", line (\d+)', error_logs)
line_number = int(line_match.group(1)) if line_match else None
# 4. Classification & Symbol Extraction
error_type = "UnknownError"
symbol = None
invalid_arg = None
# AttributeError: 'Scene' object has no attribute 'play_text'
if "AttributeError" in last_line:
error_type = "AttributeError"
match = re.search(r"has no attribute '([^']+)'", last_line)
if match:
symbol = match.group(1)
# NameError: name 'ShowCreation' is not defined
elif "NameError" in last_line:
error_type = "NameError"
match = re.search(r"name '([^']+)' is not defined", last_line)
if match:
symbol = match.group(1)
# TypeError: play() got an unexpected keyword argument 'run_time_extra'
elif "TypeError" in last_line:
error_type = "TypeError"
# Function/Class match: "TypeError: play() got..."
match_func = re.search(r"(?:TypeError:\s*)?(\w+)\(\)", last_line)
if match_func:
symbol = match_func.group(1)
# Arg match
match_arg = re.search(r"unexpected keyword argument '([^']+)'", last_line)
if match_arg:
invalid_arg = match_arg.group(1)
# ImportError: cannot import name 'X' from 'Y'
elif "ImportError" in last_line or "ModuleNotFoundError" in last_line:
error_type = "ImportError"
match = re.search(r"cannot import name '([^']+)'", last_line)
if not match:
match = re.search(r"No module named '([^']+)'", last_line)
if match:
symbol = match.group(1)
# SyntaxError: invalid syntax (file, line N)
elif "SyntaxError" in last_line:
error_type = "SyntaxError"
# LaTeX compilation error
elif "LaTeX compilation" in error_logs or "Missing $" in error_logs:
error_type = "LatexError"
symbol = "LaTeX"
# Generic catch-all for ErrorName: Message
if error_type == "UnknownError":
match = re.search(r"^(\w+Error):", last_line)
if match:
error_type = match.group(1)
return ParsedError(
error_type=error_type,
symbol=symbol,
invalid_arg=invalid_arg,
traceback_tail=traceback_tail,
line_number=line_number,
raw_message=last_line,
)
|