576df2cddd
Files changed: - .gitea/workflows/ci.yml - CHANGES.md - README.md - VERSION - instructions/mcp-read-server.md - tools/CONTRACT.md - tools/README.md - tools/chemenu/api.py - tools/chemenu/commands/doctor.py - tools/chemenu/commands/lint.py - tools/chemenu/commands/search.py - tools/chemenu/commands/types_cmd.py - tools/chemenu/config.py - tools/chemenu/corpus_cache.py - tools/chemenu/errors.py - tools/chemenu/frontmatter_io.py - tools/chemenu/lint_core.py - tools/chemenu/mcp/__init__.py - tools/chemenu/mcp/__main__.py - tools/chemenu/mcp/server.py - tools/chemenu/page.py - tools/chemenu/search/filters.py - tools/chemenu/search/registry.py - tools/chemenu/search/ripgrep.py - tools/chemenu/search/service.py - tools/chemenu/tests/conftest.py - tools/chemenu/tests/test_api.py - tools/chemenu/tests/test_corpus_cache.py - tools/chemenu/tests/test_doctor.py - tools/chemenu/tests/test_frontmatter_io.py - tools/chemenu/tests/test_instructions_cmd.py - tools/chemenu/tests/test_mcp_server.py - tools/chemenu/tests/test_new_page.py - tools/chemenu/tests/test_search.py - tools/chemenu/type_resolver.py - tools/chemenu/types_core.py - tools/requirements-mcp.txt
32 lines
1.3 KiB
Python
32 lines
1.3 KiB
Python
"""The exception contract at the library boundary.
|
|
|
|
The CLI reports a bad argument by printing an `ERROR` line and leaving through
|
|
`typer.Exit(1)`. That is the right answer for a terminal and the wrong one for
|
|
an in-process caller, which gets an exit code where it expected a value, plus
|
|
module-global state (`_util._declined`) surviving into its next call.
|
|
|
|
So the core raises, and the CLI adapter translates. `ChemenuError` is the one
|
|
class a library caller has to know; the two below it separate "your input was
|
|
wrong, a different argument would work" from "the machinery underneath failed",
|
|
which is the same distinction the CLI's exit codes draw.
|
|
|
|
`ValidationError` also inherits `ValueError`. Not for elegance: `PredicateError`
|
|
was a `ValueError` before this existed, and callers catch it that way.
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
|
|
class ChemenuError(Exception):
|
|
"""Base for every error this package raises deliberately."""
|
|
|
|
|
|
class ValidationError(ChemenuError, ValueError):
|
|
"""The caller's input was rejected. Re-running unchanged fails identically;
|
|
the CLI renders this as its exit-1 `ERROR` line."""
|
|
|
|
|
|
class BackendError(ChemenuError, RuntimeError):
|
|
"""A dependency the core relies on was missing or failed - `rg` absent, a
|
|
search that had to be killed. Not the caller's argument, and not
|
|
necessarily permanent."""
|