Skip to content

Add config-specific exception hierarchy, validation checks, and CLI validation checks, and CLI error handling#2319

Open
idoudali wants to merge 1 commit intomainfrom
idoudali/config-exceptions
Open

Add config-specific exception hierarchy, validation checks, and CLI validation checks, and CLI error handling#2319
idoudali wants to merge 1 commit intomainfrom
idoudali/config-exceptions

Conversation

@idoudali
Copy link
Copy Markdown
Contributor

@idoudali idoudali commented Mar 26, 2026

Description

Introduce dedicated config exception types and add explicit configuration checks to catch invalid or missing values early. Wire these failures into the CLI global handler so users get clearer, consistent error messages. Improve current file checks during configuration parsing

Related issues

Fixes # (issue)

Before submitting

  • This PR only changes documentation. (You can ignore the following checks in that case)
  • Did you read the contributor guideline Pull Request guidelines?
  • Did you link the issue(s) related to this PR in the section above?
  • Did you add / update tests where needed?

Reviewers

At least one review from a member of oumi-ai/oumi-staff is required.

@idoudali idoudali requested a review from oelachqar March 26, 2026 12:06
@idoudali idoudali self-assigned this Mar 26, 2026
Copilot AI review requested due to automatic review settings March 26, 2026 12:06
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a configuration-specific exception hierarchy and uses it to fail fast on invalid/missing config file paths, then surfaces these failures as cleaner CLI errors.

Changes:

  • Introduce OumiConfigError / ConfigFileNotFoundError and export them from oumi.core.configs.
  • Add explicit “path exists and is a file” checks in config loading/saving and in LoRA adapter config discovery/reading (including wrapping read/JSON errors).
  • Add unit tests covering the new exception hierarchy and the new validation/error-handling paths.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
tests/unit/core/configs/test_base_config.py Adds tests for config exception hierarchy and file/path validation behaviors in BaseConfig.
tests/unit/core/configs/params/test_model_params.py Adds tests for adapter config path/file validation and read/JSON error wrapping.
src/oumi/core/configs/params/model_params.py Validates adapter config path is a file; wraps adapter-config read/JSON errors as OumiConfigError.
src/oumi/core/configs/exceptions.py Introduces new config exception types.
src/oumi/core/configs/base_config.py Adds file existence checks and wraps YAML save OSError as OumiConfigError.
src/oumi/core/configs/init.py Re-exports the new config exception types.
src/oumi/cli/main.py Adds a top-level OumiConfigError handler to print a user-friendly error and exit.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +132 to 137
if not Path(config_path).is_file():
raise ConfigFileNotFoundError(
f"Config file not found or path is not a file: {config_path}"
)
with open(config_path) as f:
stringified_config = f.read()
Copy link

Copilot AI Mar 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

_read_config_without_interpolation() now checks is_file() but still calls open() without handling permission/IO errors. If the file exists but is unreadable (e.g., permission denied), this will raise a raw OSError and bypass the new OumiConfigError/CLI-friendly path. Consider catching OSError around the file read and re-raising as OumiConfigError with the path included (while preserving the original exception via from).

Copilot uses AI. Check for mistakes.
return app()
except OumiConfigError as e:
logging.getLogger(__name__).debug(traceback.format_exc())
CONSOLE.print(f"[red]Error: {e}[/red]")
Copy link

Copilot AI Mar 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CONSOLE.print(f"[red]Error: {e}[/red]") uses Rich markup interpolation with an exception message that may contain [/] or other markup-like sequences. That can lead to malformed markup and potentially raise during error handling, hiding the original config error. Prefer printing with style="red" (or escaping the message) so exception text is treated as plain text.

Suggested change
CONSOLE.print(f"[red]Error: {e}[/red]")
CONSOLE.print(f"Error: {e}", style="red")

Copilot uses AI. Check for mistakes.
Comment on lines +370 to 374
except OumiConfigError as e:
logging.getLogger(__name__).debug(traceback.format_exc())
CONSOLE.print(f"[red]Error: {e}[/red]")
sys.exit(1)
except Exception as e:
Copy link

Copilot AI Mar 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new top-level CLI handler only treats OumiConfigError as a user-facing configuration error, but most config validation in this repo raises ValueError (e.g., in ModelParams and many other config/params classes). As a result, many invalid-config cases will still fall into the generic except Exception branch and print a full traceback. If the intent is consistent user-friendly config errors, consider also handling ValueError (or normalizing validation errors to OumiConfigError).

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will be handled in a separate PR

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated 3 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Returns:
BaseConfig: The merged configuration object.
"""
if not Path(config_path).is_file():
Copy link

Copilot AI Mar 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

from_yaml() now checks Path(config_path).is_file() and then (in the default ignore_interpolation=True path) calls _read_config_without_interpolation(), which performs the same is_file() check again. Consider centralizing the check (e.g., rely on _read_config_without_interpolation for that branch, or factor out a shared helper) to avoid redundant filesystem stats and duplicated error logic.

Suggested change
if not Path(config_path).is_file():
if not ignore_interpolation and not Path(config_path).is_file():

Copilot uses AI. Check for mistakes.
return app()
except OumiConfigError as e:
logging.getLogger(__name__).debug(traceback.format_exc())
CONSOLE.print(f"[red]Error: {e}[/red]")
Copy link

Copilot AI Mar 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CLI error formatting here differs from the pattern used elsewhere in the CLI ([red]Error:[/red] ... in e.g. cli/analyze.py and cli/deploy.py). For consistency, consider using the same [red]Error:[/red] {e} formatting (and keep only the “Error:” prefix styled).

Suggested change
CONSOLE.print(f"[red]Error: {e}[/red]")
CONSOLE.print(f"[red]Error:[/red] {e}")

Copilot uses AI. Check for mistakes.
…rror handling

Introduce dedicated config exception types and add explicit
configuration checks to catch invalid or missing values early. Wire
these failures into the CLI global handler so users get clearer,
consistent error messages. Improve current file checks during
configuration parsing.

Fixes OPE-1848
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants