How Open Notebook's Error Classification System Translates LLM Provider Exceptions to User-Friendly Messages
Open Notebook centralizes LLM provider exception handling through the classify_error utility in open_notebook/utils/error_classifier.py, which maps technical errors like HTTP 401 or 429 responses to standardized, actionable user messages via keyword-based pattern matching.
Open Notebook is an open-source knowledge management platform that integrates multiple AI providers including OpenAI, Anthropic, and Groq. When these external services fail, the application must translate technical provider errors into actionable feedback for end users. The repository implements a robust error classification system that centralizes exception handling across all graph nodes and API layers, ensuring users receive consistent guidance regardless of which underlying provider raised the error.
The Centralized Error Classification Architecture
The error classification system isolates provider-specific error vocabularies behind a single utility function. Located at open_notebook/utils/error_classifier.py, the classify_error function serves as the sole translation layer between raw provider exceptions and the application's public error types defined in open_notebook/exceptions.py.
Every graph node that invokes language models—such as those in open_notebook/graphs/chat.py and open_notebook/graphs/ask.py—wraps provider calls in try/except blocks. When exceptions bubble up from the underlying SDKs, they are immediately passed to classify_error for normalization before propagation to the API layer.
How the classify_error Function Maps Provider Exceptions
The classify_error function implements a deterministic keyword matching algorithm to categorize errors. It constructs a normalized search string by combining the exception type name and message:
combined = f"{error_type_name}: {error_str}"
This combined string is then evaluated against the _CLASSIFICATION_RULES table. Each rule is a tuple containing:
- A list of keywords (e.g.,
"authentication","401","rate limit") - The target exception class from
open_notebook/exceptions.py - An optional user-friendly message (or
Noneto forward the original text)
The function returns the first matching rule's exception class and prepared message.
The Classification Rules Table
The _CLASSIFICATION_RULES table in error_classifier.py defines specific mappings for common failure modes:
- Authentication failures: Keywords like
"authentication","401", or"invalid api key"map toAuthenticationErrorwith the message "Authentication failed. Please check your API key in Settings → Credentials." - Rate limiting: Keywords like
"rate limit","429", or"too many requests"map toRateLimitErrorwith the message "Rate limit exceeded. Please wait a moment and try again." - Payload size violations: Keywords like
"payload too large"or"413"map toExternalServiceErrorwith the message "The request payload is too large for the AI provider. Try reducing the content size or using a different model." - Network connectivity: Keywords like
"connecterror","timeout", or"connection refused"map toNetworkErrorwith the message "Could not connect to the AI provider. Please check your network connection and provider URL."
Implementation in Graph Nodes
Graph nodes implement the error classification system by catching raw provider exceptions and re-raising them as standardized OpenNotebookError subclasses. This pattern appears consistently across the codebase:
from open_notebook.utils.error_classifier import classify_error
from open_notebook.exceptions import OpenNotebookError
try:
response = await provider.chat(messages)
except Exception as e:
# Convert raw provider error → classified error + user message
error_cls, user_msg = classify_error(e)
# Raise the mapped OpenNotebookError so the API layer can handle it uniformly
raise error_cls(user_msg) from e
This approach ensures that the API layer receives only standardized exception types, keeping internal provider details hidden from the UI.
Unit Test Validation
The classification logic is validated in the test suite. For example, testing HTTP 413 handling:
from open_notebook.utils.error_classifier import classify_error
from open_notebook.exceptions import ExternalServiceError
exc = Exception("HTTP 413: Payload Too Large")
cls, msg = classify_error(exc)
assert cls is ExternalServiceError
assert "payload is too large" in msg.lower()
Fallback Handling and Logging
When classify_error encounters an unrecognized exception that matches no rules in the table, it implements a defensive fallback strategy. The function logs a warning containing the original error details and returns ExternalServiceError with a truncated version of the original message. This ensures that even novel provider errors surface to users as generic external service failures rather than exposing internal stack traces.
The API routers then catch these classified exceptions and return appropriate HTTP error responses containing only the user-friendly text, maintaining security by hiding internal implementation details.
Summary
- Centralized classification: The
classify_errorfunction inopen_notebook/utils/error_classifier.pyprovides a single point of translation for all LLM provider exceptions. - Keyword-based mapping: The system uses a
_CLASSIFICATION_RULEStable to match error type names and messages against known patterns, returning appropriateOpenNotebookErrorsubclasses. - Consistent user experience: Graph nodes in
open_notebook/graphs/chat.pyand similar files wrap provider calls to ensure users receive actionable messages like "Authentication failed" or "Rate limit exceeded" instead of raw HTTP status codes. - Defensive fallbacks: Unmatched errors default to
ExternalServiceErrorwith truncated messages, preventing data leakage while maintaining system stability.
Frequently Asked Questions
How does Open Notebook handle unrecognized LLM provider errors?
When the classify_error function encounters an exception that matches no keywords in the _CLASSIFICATION_RULES table, it logs a warning with the original error details and falls back to ExternalServiceError with a truncated message. This ensures users receive a generic "External service error" message rather than internal technical details, while developers can still diagnose issues through application logs.
Where is the error classification logic implemented in the Open Notebook codebase?
The core classification logic resides in open_notebook/utils/error_classifier.py, specifically within the classify_error function. The public exception hierarchy is defined in open_notebook/exceptions.py, including classes like AuthenticationError, RateLimitError, and NetworkError. Graph implementations that utilize this system are located in files like open_notebook/graphs/chat.py and open_notebook/graphs/ask.py.
Can I customize the user-friendly error messages in Open Notebook?
Yes, the user-friendly messages are defined as strings in the _CLASSIFICATION_RULES tuples within error_classifier.py. Each rule contains an optional message parameter that overrides the original provider error text. Modifying these strings will change the feedback presented to users throughout the application, while the exception class mapping ensures API responses remain consistent.
What types of LLM provider errors does the classification system recognize?
The system recognizes specific patterns for authentication failures (401, invalid keys), rate limiting (429, too many requests), payload size violations (413), network connectivity issues (timeouts, connection refused), and model availability errors. Each category maps to a specific exception class in open_notebook/exceptions.py, enabling the API layer to return appropriate HTTP status codes and user guidance.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →