Skip to content

sanity_check raises UnwrapFailedError on malformed JSON instead of returning validation error #253

@shekharhimanshu

Description

@shekharhimanshu

When running sanity_check() on a dataset containing a malformed JSON file, the function raises an UnwrapFailedError exception instead of gracefully reporting the JSON parsing error as a validation failure.

Expected Behavior
The sanity check should catch JSON parsing errors and report them as validation errors in the SanityResult, e.g.:
Validation Error: Invalid JSON in <filename> at line 8, column 5 - Expecting property name enclosed in double quotes

Actual Behavior
An unhandled UnwrapFailedError exception is raised, which makes it difficult for callers to:

  • Understand what went wrong (the actual JSONDecodeError is buried in the exception chain)
  • Handle validation failures gracefully
  • Report meaningful error messages to users

Root Cause
In in t4_devkit/sanity/format/base.py, the check method calls .unwrap() without handling Failure:

def check(self, context: SanityContext) -> list[Reason] | None:
    filepath = context.to_schema_file(self.schema).unwrap()

    if self.schema.is_optional() and not filepath.exists():
        return None

    records = load_json_safe(filepath)
    return _build_records(self.schema, records.unwrap())  # ← crashes here on malformed JSON

Suggested Fix
Handle the Failure case before calling .unwrap():

def check(self, context: SanityContext) -> list[Reason] | None:
    filepath_result = context.to_schema_file(self.schema)
    if isinstance(filepath_result, Failure):
        return [Reason(f"Failed to resolve schema file: {filepath_result.failure()}")]
    filepath = filepath_result.unwrap()

    if self.schema.is_optional() and not filepath.exists():
        return None

    records = load_json_safe(filepath)
    if isinstance(records, Failure):
        return [Reason(f"Failed to parse {filepath.name}: {records.failure()}")]
    return _build_records(self.schema, records.unwrap())

Environment
t4-devkit version: 0.5.2
Python version: 3.12

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingwontfixThis will not be worked on

    Type

    No fields configured for Bug.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions