Exception Hierarchy
The exception hierarchy provides typed, domain-specific exceptions for all Pyrite error conditions. All exceptions inherit from `PyriteError`, which itself extends Python's built-in `Exception`. This replaces generic `ValueError` / `PermissionError` usage with structured errors that can be caught precisely and mapped to appropriate HTTP status codes at the API boundary.
Key Files
| File | Purpose | |------|---------| | `pyrite/exceptions.py` | Defines `PyriteError` base and all specific exception classes | | `pyrite/server/endpoints/entries.py` | Maps exceptions to HTTP status codes in API handlers | | `pyrite/server/mcp_server.py` | Catches `PyriteError` and `ConfigError` in MCP tool handlers |
API / Key Classes
Exception Classes
| Exception | Description | |-----------|-------------| | `PyriteError` | Base exception for all Pyrite errors | | `EntryNotFoundError` | Raised when an entry cannot be found by ID | | `KBNotFoundError` | Raised when a knowledge base cannot be found by name | | `KBReadOnlyError` | Raised when attempting to write to a read-only (subscribed) KB | | `ValidationError` | Raised when entry data fails validation (bad frontmatter, missing fields, etc.) | | `PluginError` | Raised when a plugin operation fails | | `StorageError` | Raised when a storage/database operation fails | | `ConfigError` | Raised when configuration is invalid |
HTTP Status Code Mapping
The REST API endpoints in `pyrite/server/endpoints/entries.py` use a consistent pattern to translate exceptions into HTTP responses:
| Exception(s) | HTTP Status | Error Code | |--------------|-------------|------------| | `KBNotFoundError`, `EntryNotFoundError` | 404 Not Found | `NOT_FOUND` | | `KBReadOnlyError` | 403 Forbidden | `READ_ONLY` | | `ValidationError`, `PyriteError`, `ValueError` | 400 Bad Request | `CREATE_FAILED` / `UPDATE_FAILED` / `DELETE_FAILED` |
This pattern is applied uniformly in the create, update, and delete entry handlers. Each handler wraps its service call in a try/except block that catches the three exception groups in order of specificity.
In the MCP server, `PyriteError` is caught generically and returned as tool error text, since MCP does not use HTTP status codes.