Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

docs, core: error messaging [wip] #27397

Merged
merged 20 commits into from
Oct 17, 2024
Prev Previous commit
Next Next commit
x
  • Loading branch information
efriis committed Oct 17, 2024
commit 5b7da91178937890c3264e13d55165386385adcf
69 changes: 6 additions & 63 deletions libs/core/langchain_core/errors.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,66 +11,9 @@ class ErrorCode(Enum):
OUTPUT_PARSING_FAILURE = "OUTPUT_PARSING_FAILURE"


class LangChainException(Exception): # noqa: N818
"""Base exception class for LangChain errors."""

def __init__(self, message: str, error_code: ErrorCode):
self.message = message
self.error_code = error_code
super().__init__(self.message)

def __str__(self):
return (
f'{self.__class__.__name__}("{self.message}")\n'
"For troubleshooting, visit: https://python.langchain.com/docs/"
f"troubleshooting/errors/{self.error_code.value}"
)


class InvalidPromptInputError(LangChainException):
"""Exception raised for invalid prompt input errors."""

def __init__(self, message: str):
super().__init__(message, ErrorCode.INVALID_PROMPT_INPUT)


class InvalidToolResultsError(LangChainException):
"""Exception raised for invalid tool results."""

def __init__(self, message: str):
super().__init__(message, ErrorCode.INVALID_TOOL_RESULTS)


class MessageCoercionFailureError(LangChainException):
"""Exception raised for message coercion failures."""

def __init__(self, message: str):
super().__init__(message, ErrorCode.MESSAGE_COERCION_FAILURE)


class ModelAuthenticationError(LangChainException):
"""Exception raised for model authentication errors."""

def __init__(self, message: str):
super().__init__(message, ErrorCode.MODEL_AUTHENTICATION)


class ModelNotFoundError(LangChainException):
"""Exception raised when a model is not found."""

def __init__(self, message: str):
super().__init__(message, ErrorCode.MODEL_NOT_FOUND)


class ModelRateLimitError(LangChainException):
"""Exception raised for model rate limit errors."""

def __init__(self, message: str):
super().__init__(message, ErrorCode.MODEL_RATE_LIMIT)


class OutputParsingFailureError(LangChainException):
"""Exception raised for output parsing failures."""

def __init__(self, message: str):
super().__init__(message, ErrorCode.OUTPUT_PARSING_FAILURE)
def create_message(*, message: str, error_code: ErrorCode) -> str:
return (
f"{message}\n"
"For troubleshooting, visit: https://python.langchain.com/docs/"
f"troubleshooting/errors/{error_code.value}"
)
28 changes: 21 additions & 7 deletions libs/core/langchain_core/prompts/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
from pydantic import BaseModel, ConfigDict, Field, model_validator
from typing_extensions import Self, override

from langchain_core.errors import InvalidPromptInputError
from langchain_core.errors import ErrorCode, create_message
from langchain_core.load import dumpd
from langchain_core.output_parsers.base import BaseOutputParser
from langchain_core.prompt_values import (
Expand Down Expand Up @@ -52,7 +52,7 @@
"""optional_variables: A list of the names of the variables for placeholder
or MessagePlaceholder that are optional. These variables are auto inferred
from the prompt and user need not provide them."""
input_types: typing.Dict[str, Any] = Field(

Check failure on line 55 in libs/core/langchain_core/prompts/base.py

View workflow job for this annotation

GitHub Actions / cd libs/core / make lint #3.10

Ruff (UP006)

langchain_core/prompts/base.py:55:18: UP006 Use `dict` instead of `typing.Dict` for type annotation

Check failure on line 55 in libs/core/langchain_core/prompts/base.py

View workflow job for this annotation

GitHub Actions / cd libs/core / make lint #3.11

Ruff (UP006)

langchain_core/prompts/base.py:55:18: UP006 Use `dict` instead of `typing.Dict` for type annotation

Check failure on line 55 in libs/core/langchain_core/prompts/base.py

View workflow job for this annotation

GitHub Actions / cd libs/core / make lint #3.12

Ruff (UP006)

langchain_core/prompts/base.py:55:18: UP006 Use `dict` instead of `typing.Dict` for type annotation

Check failure on line 55 in libs/core/langchain_core/prompts/base.py

View workflow job for this annotation

GitHub Actions / cd libs/core / make lint #3.9

Ruff (UP006)

langchain_core/prompts/base.py:55:18: UP006 Use `dict` instead of `typing.Dict` for type annotation
default_factory=dict, exclude=True
) # noqa: UP006
"""A dictionary of the types of the variables the prompt template expects.
Expand All @@ -77,18 +77,24 @@
"Cannot have an input variable named 'stop', as it is used internally,"
" please rename."
)
raise InvalidPromptInputError(msg)
raise ValueError(
create_message(message=msg, error_code=ErrorCode.INVALID_PROMPT_INPUT)
)
if "stop" in self.partial_variables:
msg = (
"Cannot have an partial variable named 'stop', as it is used "
"internally, please rename."
)
raise InvalidPromptInputError(msg)
raise ValueError(
create_message(message=msg, error_code=ErrorCode.INVALID_PROMPT_INPUT)
)

overall = set(self.input_variables).intersection(self.partial_variables)
if overall:
msg = f"Found overlapping input and partial variables: {overall}"
raise InvalidPromptInputError(msg)
raise ValueError(
create_message(message=msg, error_code=ErrorCode.INVALID_PROMPT_INPUT)
)
return self

@classmethod
Expand Down Expand Up @@ -151,7 +157,11 @@
f"Expected mapping type as input to {self.__class__.__name__}. "
f"Received {type(inner_input)}."
)
raise InvalidPromptInputError(msg)
raise TypeError(
create_message(
message=msg, error_code=ErrorCode.INVALID_PROMPT_INPUT
)
)
missing = set(self.input_variables).difference(inner_input)
if missing:
msg = (
Expand All @@ -165,7 +175,9 @@
" and not a variable, please escape it with double curly braces like: "
f"'{{{{{example_key}}}}}'."
)
raise InvalidPromptInputError(msg)
raise KeyError(
create_message(message=msg, error_code=ErrorCode.INVALID_PROMPT_INPUT)
)
return inner_input

def _format_prompt_with_error_handling(self, inner_input: dict) -> PromptValue:
Expand Down Expand Up @@ -384,7 +396,9 @@
f"{required_metadata}. Received document with missing metadata: "
f"{list(missing_metadata)}."
)
raise InvalidPromptInputError(msg)
raise ValueError(
create_message(message=msg, error_code=ErrorCode.INVALID_PROMPT_INPUT)
)
return {k: base_info[k] for k in prompt.input_variables}


Expand Down
18 changes: 0 additions & 18 deletions libs/core/tests/unit_tests/test_errors.py

This file was deleted.

Loading