From e0099a0d8440dda7edd9e4997ea36e42063ee693 Mon Sep 17 00:00:00 2001 From: nicolassanchez02 <98576999+nicolassanchez02@users.noreply.github.com> Date: Fri, 29 May 2026 01:20:05 -0500 Subject: [PATCH] convert/tech_subprocessor: contextual KeyErrors on unmapped IDs When the converter hits an AoE2 attribute or resource ID that hasn't been mapped to an openage API property, the lookup raises a bare "KeyError: 208" with no hint of what 208 means. Triaging those reports takes a full trace read just to figure out whether the missing mapping is an attribute, a resource, or DE2-specific. Wrap the four upgrade_*_funcs[id] lookups in AoC and DE2 tech_subprocessor with try/except + raise from, so the message names the category (attribute vs resource, AoC vs DE2) and preserves the original KeyError for the trace. Same pattern can be applied to the other dict-by-ID lookups in the converter; this PR is just the spot called out in the issue plus its direct AoC parent, to establish the pattern. Happy to extend the sweep if maintainers prefer one big PR. Refs #1344. --- .../conversion/aoc/tech_subprocessor.py | 18 +++++++++++++++--- .../conversion/de2/tech_subprocessor.py | 18 +++++++++++++++--- 2 files changed, 30 insertions(+), 6 deletions(-) diff --git a/openage/convert/processor/conversion/aoc/tech_subprocessor.py b/openage/convert/processor/conversion/aoc/tech_subprocessor.py index 3bcd64a55b..dfb5df620a 100644 --- a/openage/convert/processor/conversion/aoc/tech_subprocessor.py +++ b/openage/convert/processor/conversion/aoc/tech_subprocessor.py @@ -1,4 +1,4 @@ -# Copyright 2020-2023 the openage authors. See copying.md for legal info. +# Copyright 2020-2026 the openage authors. See copying.md for legal info. # # pylint: disable=too-many-locals,too-many-statements,too-many-branches # @@ -241,7 +241,13 @@ def attribute_modify_effect( else: return patches - upgrade_func = AoCTechSubprocessor.upgrade_attribute_funcs[attribute_type] + try: + upgrade_func = AoCTechSubprocessor.upgrade_attribute_funcs[attribute_type] + except KeyError as exc: + raise KeyError( + f"No subprocessor function found for handling upgrade of " + f"unit attribute: {attribute_type}" + ) from exc for affected_entity in affected_entities: patches.extend(upgrade_func(converter_group, affected_entity, value, operator, team)) @@ -284,7 +290,13 @@ def resource_modify_effect( # 21 = tech count (unused) return patches - upgrade_func = AoCTechSubprocessor.upgrade_resource_funcs[resource_id] + try: + upgrade_func = AoCTechSubprocessor.upgrade_resource_funcs[resource_id] + except KeyError as exc: + raise KeyError( + f"No subprocessor function found for handling upgrade of " + f"resource: {resource_id}" + ) from exc patches.extend(upgrade_func(converter_group, value, operator, team)) return patches diff --git a/openage/convert/processor/conversion/de2/tech_subprocessor.py b/openage/convert/processor/conversion/de2/tech_subprocessor.py index 7bce1d1163..11ffa1b6c7 100644 --- a/openage/convert/processor/conversion/de2/tech_subprocessor.py +++ b/openage/convert/processor/conversion/de2/tech_subprocessor.py @@ -1,4 +1,4 @@ -# Copyright 2020-2024 the openage authors. See copying.md for legal info. +# Copyright 2020-2026 the openage authors. See copying.md for legal info. # # pylint: disable=too-many-locals,too-many-branches @@ -303,7 +303,13 @@ def attribute_modify_effect( else: return patches - upgrade_func = DE2TechSubprocessor.upgrade_attribute_funcs[attribute_type] + try: + upgrade_func = DE2TechSubprocessor.upgrade_attribute_funcs[attribute_type] + except KeyError as exc: + raise KeyError( + f"No DE2 subprocessor function found for handling upgrade of " + f"unit attribute: {attribute_type}" + ) from exc for affected_entity in affected_entities: patches.extend(upgrade_func(converter_group, affected_entity, value, operator, team)) @@ -346,7 +352,13 @@ def resource_modify_effect( # 21 = tech count (unused) return patches - upgrade_func = DE2TechSubprocessor.upgrade_resource_funcs[resource_id] + try: + upgrade_func = DE2TechSubprocessor.upgrade_resource_funcs[resource_id] + except KeyError as exc: + raise KeyError( + f"No DE2 subprocessor function found for handling upgrade of " + f"civ resource: {resource_id}" + ) from exc patches.extend(upgrade_func(converter_group, value, operator, team)) return patches