feat: better error msg & tests
All checks were successful
build / build (push) Successful in 2m9s
build / trigger-build-image (push) Successful in 12s

This commit is contained in:
Boming Zhang 2025-09-17 15:54:27 -07:00
parent 6795290d7c
commit 8150d3d770
No known key found for this signature in database
GPG Key ID: 134DACA8458EB0E3
5 changed files with 40 additions and 4 deletions

View File

@ -5,7 +5,7 @@ from typing import Any, Dict, Tuple, Type, cast
import inquirer import inquirer
import tomli import tomli
import yaml import yaml
from pydantic import AliasChoices, BaseModel from pydantic import AliasChoices, BaseModel, ValidationError
from joj3_config_generator.models import answer, joj1, repo, task from joj3_config_generator.models import answer, joj1, repo, task
from joj3_config_generator.models.common import Memory, Time from joj3_config_generator.models.common import Memory, Time
@ -166,10 +166,22 @@ def load_joj3_toml(
repo_obj = tomli.loads(repo_toml_path.read_text()) repo_obj = tomli.loads(repo_toml_path.read_text())
task_obj = tomli.loads(task_toml_path.read_text()) task_obj = tomli.loads(task_toml_path.read_text())
repo_conf = repo.Config(**repo_obj) try:
repo_conf = repo.Config(**repo_obj)
except ValidationError as e:
logger.error(
f"Error parsing {repo_toml_path}, most likely to be unknown fields, check the latest sample toml carefully:\n{e}"
)
raise
repo_conf.root = root_path repo_conf.root = root_path
repo_conf.path = repo_toml_path.relative_to(root_path) repo_conf.path = repo_toml_path.relative_to(root_path)
task_conf = task.Config(**task_obj) try:
task_conf = task.Config(**task_obj)
except ValidationError as e:
logger.error(
f"Error parsing {task_toml_path}, most likely to be unknown fields, check the latest sample toml carefully:\n{e}"
)
raise
task_conf.root = root_path task_conf.root = root_path
task_conf.path = task_toml_path.relative_to(root_path) task_conf.path = task_toml_path.relative_to(root_path)
check_unnecessary_fields(repo.Config, repo_obj, repo_toml_path) check_unnecessary_fields(repo.Config, repo_obj, repo_toml_path)

View File

@ -94,6 +94,7 @@ def convert(
""" """
app.pretty_exceptions_enable = False app.pretty_exceptions_enable = False
logger.info(f"Converting files in {root.absolute()}") logger.info(f"Converting files in {root.absolute()}")
error_json_paths = []
for repo_toml_path in root.glob("**/repo.toml"): for repo_toml_path in root.glob("**/repo.toml"):
if not any(p != repo_toml_path for p in repo_toml_path.parent.glob("*.toml")): if not any(p != repo_toml_path for p in repo_toml_path.parent.glob("*.toml")):
fallback_toml_path = repo_toml_path.parent / "conf.toml" fallback_toml_path = repo_toml_path.parent / "conf.toml"
@ -109,7 +110,13 @@ def convert(
logger.info( logger.info(
f"Converting {repo_toml_path} & {task_toml_path} to {result_json_path}" f"Converting {repo_toml_path} & {task_toml_path} to {result_json_path}"
) )
repo_conf, task_conf = load_joj3_toml(root, repo_toml_path, task_toml_path) try:
repo_conf, task_conf = load_joj3_toml(
root, repo_toml_path, task_toml_path
)
except Exception:
error_json_paths.append(result_json_path)
continue
result_model = convert_joj3_conf(repo_conf, task_conf) result_model = convert_joj3_conf(repo_conf, task_conf)
result_dict = result_model.model_dump( result_dict = result_model.model_dump(
mode="json", by_alias=True, exclude_none=True mode="json", by_alias=True, exclude_none=True
@ -117,3 +124,8 @@ def convert(
with result_json_path.open("w", newline="") as result_file: with result_json_path.open("w", newline="") as result_file:
json.dump(result_dict, result_file, ensure_ascii=False, indent=4) json.dump(result_dict, result_file, ensure_ascii=False, indent=4)
result_file.write("\n") result_file.write("\n")
if error_json_paths:
logger.error(
f"Failed to convert {len(error_json_paths)} file(s): {', '.join(str(json_path) for json_path in error_json_paths)}. Check previous errors for details."
)
raise typer.Exit(code=1)

View File

View File

@ -0,0 +1,4 @@
name = "extra-field"
extra-field = "extra-field value"
extra-dict.extra-field = "extra-dict.extra-field value"
limit.extra-field = "limit.extra-field value"

View File

@ -1,3 +1,6 @@
import pytest
from pydantic import ValidationError
from tests.convert.utils import load_case from tests.convert.utils import load_case
@ -29,6 +32,11 @@ def test_empty() -> None:
load_case("empty") load_case("empty")
def test_extra_field() -> None:
with pytest.raises(ValidationError):
load_case("extra-field")
def test_full() -> None: def test_full() -> None:
load_case("full") load_case("full")