Batu Lab NotesPractical developer guides

Use try else to separate successful parsing from recovery

By Batu · English technical notes

Use try/else by placing only json.loads() in try, handling JSONDecodeError in except, and putting work that requires parsed data in else. In the direct example below, that means else runs for '{}' and except reports JSONDecodeError for the malformed string '{'.

The intentionally wrong helper shows why placement matters. It parses '{}', then runs a separate rendering step inside a broad try. The synthetic rendering failure is reported as “recovery,” despite not being a JSON parsing error. That label hides ownership: the parser succeeded, while later work failed. The corrected parse_with_separate_success_path() narrows the protected suite to json.loads(text). Its handler is specific to json.JSONDecodeError, and the else suite records the parsed value only when loading finished without an exception.

The assertions are deliberately modest. They establish the branch events for these two exact inputs; they do not validate arbitrary JSON, repair malformed text, or prove that downstream work cannot fail. If success-path work needs its own recovery policy, give it a separate boundary and exception type instead of enlarging the parsing boundary. The Python tutorial recommends else because it avoids accidentally catching exceptions from code that was not meant to be protected. Python error handling tutorial and json.loads documentation.

AI-assistance disclosure: This article was drafted with AI assistance and uses deterministic in-memory strings.

import json


def wrongly_labels_post_parse_failure(text):
    try:
        json.loads(text)
        raise RuntimeError("render failed")
    except Exception as error:
        return f"recovery: {type(error).__name__}"


def parse_with_separate_success_path(text, events):
    try:
        value = json.loads(text)
    except json.JSONDecodeError as error:
        events.append(f"except: {type(error).__name__}")
    else:
        events.append(f"else: {value}")


print(f"wrong {{}}: {wrongly_labels_post_parse_failure('{}')}")
events = []
parse_with_separate_success_path("{}", events)
parse_with_separate_success_path("{", events)
assert events == ["else: {}", "except: JSONDecodeError"]
print(f"correct: {events}")
wrong {}: recovery: RuntimeError
correct: ['else: {}', 'except: JSONDecodeError']