Skip to content

Commit 8c25db8

Browse files
committed
feat(robot): display filename on TOML parsing error
1 parent f6e380c commit 8c25db8

File tree

1 file changed

+29
-7
lines changed
  • packages/robot/src/robotcode/robot/config

1 file changed

+29
-7
lines changed

packages/robot/src/robotcode/robot/config/loader.py

Lines changed: 29 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -55,14 +55,36 @@ def __init__(self, path: Path, *args: Any, **kwargs: Any) -> None:
5555
_ConfigType = TypeVar("_ConfigType", bound=BaseOptions)
5656

5757

58+
class InvalidTomlError(ValueError):
59+
pass
60+
61+
62+
class InvalidTomlFileError(ValueError):
63+
pass
64+
65+
66+
def _load_toml(data: Union[str, Path]) -> Dict[str, Any]:
67+
file = None
68+
if isinstance(data, Path):
69+
file = data
70+
data = data.read_text("utf-8")
71+
72+
try:
73+
return tomllib.loads(data)
74+
except tomllib.TOMLDecodeError as e:
75+
if file:
76+
raise InvalidTomlFileError(f"Invalid TOML file'{file.absolute()}': {e}") from e
77+
raise InvalidTomlError(f"Invalid TOML: {e}") from e
78+
79+
5880
def load_robot_config_from_robot_toml_str(__s: str) -> RobotConfig:
5981
return load_config_from_robot_toml_str(RobotConfig, __s)
6082

6183

6284
def load_config_from_robot_toml_str(
63-
config_type: Type[_ConfigType], data: Union[str, Dict[str, Any]], tool_name: Optional[str] = None
85+
config_type: Type[_ConfigType], data: Union[str, Dict[str, Any], Path], tool_name: Optional[str] = None
6486
) -> _ConfigType:
65-
dict_data = tomllib.loads(data) if isinstance(data, str) else data
87+
dict_data = _load_toml(data) if isinstance(data, (str, Path)) else data
6688

6789
if tool_name:
6890
try:
@@ -76,9 +98,9 @@ def load_config_from_robot_toml_str(
7698

7799

78100
def load_config_from_pyproject_toml_str(
79-
config_type: Type[_ConfigType], tool_name: str, data: Union[str, Dict[str, Any]]
101+
config_type: Type[_ConfigType], tool_name: str, data: Union[str, Dict[str, Any], Path]
80102
) -> _ConfigType:
81-
dict_data = tomllib.loads(data) if isinstance(data, str) else data
103+
dict_data = _load_toml(data) if isinstance(data, (str, Path)) else data
82104

83105
return from_dict(dict_data.get("tool", {}).get(tool_name, {}), config_type)
84106

@@ -93,13 +115,13 @@ def _load_config_data_from_path(
93115
try:
94116
if path.name == PYPROJECT_TOML:
95117
return load_config_from_pyproject_toml_str(
96-
config_type, pyproject_toml_tool_name, path.read_text("utf-8") if data is None else data
118+
config_type, pyproject_toml_tool_name, path if data is None else data
97119
)
98120

99121
if path.name == ROBOT_TOML or path.name == LOCAL_ROBOT_TOML or path.suffix == ".toml":
100122
return load_config_from_robot_toml_str(
101123
config_type,
102-
path.read_text("utf-8") if data is None else data,
124+
path if data is None else data,
103125
tool_name=robot_toml_tool_name,
104126
)
105127
raise TypeError("Unknown config file type.")
@@ -143,7 +165,7 @@ def load_config_from_path(
143165
verbose_callback(f"Load configuration from {__path if isinstance(__path, Path) else __path[0]}")
144166

145167
p = __path if isinstance(__path, Path) else __path[0]
146-
data = tomllib.loads(p.read_text("utf-8"))
168+
data = _load_toml(p)
147169

148170
result.add_options(
149171
_load_config_data_from_path(

0 commit comments

Comments
 (0)