1010from pydantic import BaseModel , ValidationError
1111import rich .console
1212from rich .traceback import install as install_traceback
13+ import tomllib
1314
1415from ..__about__ import __version__
1516from ..config .load import handle_config
2425from ..logging import setup_logging
2526from ..models .config .app import AppConfig
2627from ..models .config .env import EnvConfig
27- from ..utils .errors import format_pydantic_error
28+ from ..utils .errors import format_pydantic_error , format_toml_error
2829from ..utils .pidlock import LockAcquisitionError , PidFileLock
2930from .cmd_build import build
3031from .cmd_c14n import c14n
@@ -68,16 +69,16 @@ def handle_validation_error(
6869 :param ctx: The Click context, used to exit the CLI with an appropriate
6970 status code after handling the error.
7071 """
71- config_label = "Application" if model_class == AppConfig else "Environment"
72+ # Determine which file we were working on
73+ config_file = str ((config_files or ["unknown" ])[0 ])
7274
73- if isinstance (e , ValidationError ):
74- # Safely extract the first config file name for the error header
75- config_file = str ((config_files or ["unknown" ])[0 ])
76- format_pydantic_error (
77- e , model_class , config_file , verbose , console = CONSOLE
78- )
75+ if isinstance (e , tomllib .TOMLDecodeError ):
76+ format_toml_error (e , config_file , console = CONSOLE )
77+ elif isinstance (e , ValidationError ):
78+ format_pydantic_error (e , model_class , config_file , verbose , console = CONSOLE )
7979 else :
80- log .error ("%s configuration failed validation:" , config_label )
80+ config_label = "Application" if model_class == AppConfig else "Environment"
81+ log .error ("%s configuration failed:" , config_label )
8182 log .error ("Error in config file(s): %s" , config_files )
8283 log .error (e )
8384 ctx .exit (1 )
@@ -171,18 +172,26 @@ def cli(
171172 context .dry_run = dry_run
172173 context .debug = debug
173174
175+ # --- INITIALIZE TO AVOID UNBOUND ERRORS ---
176+ raw_appconfig : dict [str , Any ] = {}
177+ raw_envconfig : dict [str , Any ] = {}
178+
174179 # --- PHASE 1: Load and Validate Application Config ---
175- (
176- context .appconfigfiles ,
177- raw_appconfig ,
178- context .appconfig_from_defaults ,
179- ) = handle_config (
180- app_config ,
181- CONFIG_PATHS ,
182- APP_CONFIG_BASENAMES + PROJECT_LEVEL_APP_CONFIG_FILENAMES ,
183- None ,
184- DEFAULT_APP_CONFIG ,
185- )
180+ try :
181+ # We cast the return of handle_config to the expected tuple type
182+ result = handle_config (
183+ app_config ,
184+ CONFIG_PATHS ,
185+ APP_CONFIG_BASENAMES + PROJECT_LEVEL_APP_CONFIG_FILENAMES ,
186+ None ,
187+ DEFAULT_APP_CONFIG ,
188+ )
189+ context .appconfigfiles , raw_appconfig , context .appconfig_from_defaults = cast (
190+ tuple [tuple [Path , ...] | None , dict [str , Any ], bool ], result
191+ )
192+ except tomllib .TOMLDecodeError as e :
193+ files = (app_config ,) if app_config else None
194+ handle_validation_error (e , AppConfig , files , verbose , ctx )
186195
187196 raw_appconfig = cast (dict [str , Any ], raw_appconfig )
188197
@@ -200,18 +209,21 @@ def cli(
200209 )
201210 setup_logging (cliverbosity = verbose , user_config = {"logging" : logging_config })
202211
203- # --- PHASE 2: Load Environment Config, Validate, and Acquire Lock ---
204- (
205- context .envconfigfiles ,
206- raw_envconfig ,
207- context .envconfig_from_defaults ,
208- ) = handle_config (
209- env_config ,
210- (PROJECT_DIR ,),
211- None ,
212- DEFAULT_ENV_CONFIG_FILENAME ,
213- DEFAULT_ENV_CONFIG ,
214- )
212+ # --- PHASE 2: Load Environment Config ---
213+ try :
214+ result = handle_config (
215+ env_config ,
216+ (PROJECT_DIR ,),
217+ None ,
218+ DEFAULT_ENV_CONFIG_FILENAME ,
219+ DEFAULT_ENV_CONFIG ,
220+ )
221+ context .envconfigfiles , raw_envconfig , context .envconfig_from_defaults = cast (
222+ tuple [tuple [Path , ...] | None , dict [str , Any ], bool ], result
223+ )
224+ except tomllib .TOMLDecodeError as e :
225+ files = (env_config ,) if env_config else None
226+ handle_validation_error (e , EnvConfig , files , verbose , ctx )
215227
216228 raw_envconfig = cast (dict [str , Any ], raw_envconfig )
217229
0 commit comments