Skip to content
16 changes: 13 additions & 3 deletions src/datamorph/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -176,8 +176,18 @@ def schema_cmd(
err_console.print(f"[red]Could not detect format for: {file}[/red]")
sys.exit(1)

reader = get_reader(fmt)
schema = reader.infer_schema(file, sample_size=sample)
try:
reader = get_reader(fmt)
except ValueError as e:
err_console.print(f"[red]ERROR:[/red] {e}")
sys.exit(1)
try:
schema = reader.infer_schema(file, sample_size=sample)
except Exception as e:
err_console.print(
f"[red]ERROR:[/red] Could not infer schema from {file}: {e}"
)
sys.exit(1)

if json_output:
console.print(json.dumps(schema, indent=2))
Expand All @@ -192,7 +202,7 @@ def schema_cmd(

console.print(f"\nDetected format: [bold]{fmt}[/bold]")
console.print(table)
console.print(f"[dim]Inferred from {sample}+ rows[/dim]")
console.print(f"[dim]Inferred from a sample of up to {sample} rows[/dim]")


# ── formats ──────────────────────────────────────────────────────────
Expand Down
32 changes: 32 additions & 0 deletions tests/test_cli_error_paths.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,35 @@ def test_convert_nonexistent_file(self):
"""convert subcommand with nonexistent file shows error."""
result = runner.invoke(cli, ["convert", "/nonexistent/file.json"])
assert result.exit_code != 0


class TestSchemaCmdErrorPaths:
"""Tests for the `schema` subcommand error paths (silent-failure class)."""

def test_schema_unsupported_format_exits_cleanly(self, tmp_path):
"""--format with an unsupported name errors instead of traceback."""
f = tmp_path / "data.txt"
f.write_text("hello")
result = runner.invoke(cli, ["schema", str(f), "--format", "nope"])
assert result.exit_code == 1
assert "Unsupported format" in result.output
assert "Traceback" not in result.output

def test_schema_malformed_json_exits_cleanly(self, tmp_path):
"""Malformed input yields a clean error, not an unhandled traceback."""
f = tmp_path / "broken.json"
f.write_text("{not valid json!!!")
result = runner.invoke(cli, ["schema", str(f)])
assert result.exit_code == 1
assert "Could not infer schema" in result.output
assert "Traceback" not in result.output

def test_schema_sample_message_is_honest(self, tmp_path):
"""Footer reports the sample cap, not '{sample}+ rows'."""
import json as _json

f = tmp_path / "rows.json"
f.write_text(_json.dumps([{"a": 1}, {"a": 2}]))
result = runner.invoke(cli, ["schema", str(f), "--sample", "100"])
assert result.exit_code == 0
assert "up to 100 rows" in result.output
Loading