From 99dfb41c4af250b26bc882e78bb2281807a661f4 Mon Sep 17 00:00:00 2001 From: ItMightBeKaraoke Date: Sat, 16 May 2026 19:26:21 -0500 Subject: [PATCH 1/2] Provide context for document errors In parse_file, add line number and contents to the exception when a line fails to parse so the user has enough information to diagnose the issue. --- src/ass/document.py | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/ass/document.py b/src/ass/document.py index d919baf..fb5c56f 100644 --- a/src/ass/document.py +++ b/src/ass/document.py @@ -82,14 +82,14 @@ def parse_file(cls, f): section = None seen_sections = CaseInsensitiveOrderedDict() - for i, line in enumerate(f): + for i, raw_line in enumerate(f): if i == 0: bom_seqeunces = ("\xef\xbb\xbf", "\xff\xfe", "\ufeff") - if any(line.startswith(seq) for seq in bom_seqeunces): + if any(raw_line.startswith(seq) for seq in bom_seqeunces): raise ValueError("BOM detected. Please open the file with the proper encoding," " usually '%s'" % cls.PREFERRED_ENCODING.name) - line = line.strip() + line = raw_line.strip() if not line or line.startswith(';'): continue @@ -105,7 +105,7 @@ def parse_file(cls, f): continue if section is None: - raise ValueError('Content outside of any section.') + raise ValueError("Content outside of any section\n\n%d:%s" % (i+1, raw_line)) if ':' not in line: # illformed, ignore @@ -113,7 +113,10 @@ def parse_file(cls, f): type_name, _, line = line.partition(":") line = line.lstrip() - section.add_line(type_name, line) + try: + section.add_line(type_name, line) + except Exception as e: + raise type(e)("Failed to parse file\n\n%d:%s" % (i+1, raw_line)) from e # append default sections not present in the parsed file for section_name, section in doc.sections.items(): From 3133818e479a5f7fdf191858ae170becf4ac52b6 Mon Sep 17 00:00:00 2001 From: ItMightBeKaraoke Date: Sat, 16 May 2026 19:32:56 -0500 Subject: [PATCH 2/2] Show color in parse failure message, quote strings from user data In Color.from_ass, have the color failure message show the string that fails to parse as a color (so the user can easily see what the issue was, e.g. stray whitespace). Also in LineSection.add_line, put the failing string in quotes so it's more clear it's a literal string from the document. --- src/ass/data.py | 2 +- src/ass/section.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ass/data.py b/src/ass/data.py index 338fa7c..b3df66a 100644 --- a/src/ass/data.py +++ b/src/ass/data.py @@ -26,7 +26,7 @@ def from_ass(cls, v): """ Convert a Visual Basic (ASS) color code into an ``Color``. """ if not v.startswith("&H"): - raise ValueError("color must start with &H") + raise ValueError("color must start with &H (found '%s')" % v) rest = int(v[2:], 16) diff --git a/src/ass/section.py b/src/ass/section.py index 6469588..3e57214 100644 --- a/src/ass/section.py +++ b/src/ass/section.py @@ -36,7 +36,7 @@ def add_line(self, type_name, raw_line): self.field_order = [field.strip() for field in raw_line.split(",")] else: if self.line_parsers is not None and type_name.lower() not in self.line_parsers: - raise ValueError("unexpected {} line in {}".format(type_name, self.name)) + raise ValueError("unexpected '{}' line in {}".format(type_name, self.name)) parser = (self.line_parsers[type_name.lower()] if self.line_parsers is not None