# Exceptions and Warnings

Module exposing the exceptions that the framework raises to the calling code,
and the category of the warnings that it issues.

The exceptions are the classes that the framework itself raises, so they can be
used in `except` clauses: `from contextgem import ModelAPIError`, or
`ContextGemError`, their base class, to catch any of them. Likewise,
the warning category is the one of the warnings that the framework issues, so it
can be used in warning filters: `from contextgem import ContextGemWarning`.

### *exception* contextgem.public.exceptions.ContextGemError(message, retry_count=None, original_error=None)

Bases: [`Exception`](https://docs.python.org/3/builtins/exceptions.html#Exception)

Base class of the exceptions that the framework raises when a run fails, i.e.
of [`ModelAPIError`](#contextgem.public.exceptions.ModelAPIError), [`ModelExtractionError`](#contextgem.public.exceptions.ModelExtractionError) and
[`LLMToolLoopLimitError`](#contextgem.public.exceptions.LLMToolLoopLimitError). Catch it to handle any of them in one clause,
e.g. `except ContextGemError`.

An error in the calling code, e.g. an invalid argument or an object that
cannot be used where it is passed, is raised as `ValueError` or `TypeError`
instead, which includes the `ValidationError` of pydantic, a subclass
of `ValueError`. A file that cannot be read or written, e.g. by `from_disk()`
or `to_disk()`, raises `OSError`.

Can be imported from `contextgem`.

* **Variables:**
  * **message** ([*str*](https://docs.python.org/3/builtins/stdtypes.html#str)) – Human-readable error description
  * **retry_count** ([*int*](https://docs.python.org/3/builtins/functions.html#int) *or* *None*) – Number of retries attempted before failure
  * **original_error** ([*Exception*](https://docs.python.org/3/builtins/exceptions.html#Exception) *or* *None*) – The underlying exception that caused the failure
* **Parameters:**
  * **message** ([*str*](https://docs.python.org/3/builtins/stdtypes.html#str))
  * **retry_count** ([*int*](https://docs.python.org/3/builtins/functions.html#int) *|* *None*)
  * **original_error** ([*Exception*](https://docs.python.org/3/builtins/exceptions.html#Exception) *|* *None*)

Initialize the exception.

* **Parameters:**
  * **message** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Human-readable error description
  * **retry_count** ([`int`](https://docs.python.org/3/builtins/functions.html#int) | [`None`](https://docs.python.org/3/builtins/constants.html#None)) – Number of retries attempted before failure
  * **original_error** ([`Exception`](https://docs.python.org/3/builtins/exceptions.html#Exception) | [`None`](https://docs.python.org/3/builtins/constants.html#None)) – The underlying exception that caused the failure

### *exception* contextgem.public.exceptions.ModelAPIError(message, retry_count=None, original_error=None)

Bases: [`ContextGemError`](#contextgem.public.exceptions.ContextGemError)

Exception raised when a request to a model fails for good, and there is
no fallback model left to try.

This is the case when:

- the request fails with a non-transient error, e.g. an invalid request or
  a failed authentication;
- the request fails with a transient error (request timeout, rate limit, server
  or connection error), also after `num_retries_failed_request` retries;
- the response of an LLM is cut off at the max output tokens during extraction,
  or is empty in a chat.

During extraction, if `raise_exception_on_extraction_error=False` is passed
to the extraction method, a warning is logged instead.

Can be imported from `contextgem`.

* **Variables:**
  * **message** ([*str*](https://docs.python.org/3/builtins/stdtypes.html#str)) – Human-readable error description
  * **retry_count** ([*int*](https://docs.python.org/3/builtins/functions.html#int) *or* *None*) – Number of retries attempted for the failed request
  * **original_error** ([*Exception*](https://docs.python.org/3/builtins/exceptions.html#Exception) *or* *None*) – The underlying exception that caused the failure
* **Parameters:**
  * **message** ([*str*](https://docs.python.org/3/builtins/stdtypes.html#str))
  * **retry_count** ([*int*](https://docs.python.org/3/builtins/functions.html#int) *|* *None*)
  * **original_error** ([*Exception*](https://docs.python.org/3/builtins/exceptions.html#Exception) *|* *None*)

Initialize the exception.

* **Parameters:**
  * **message** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Human-readable error description
  * **retry_count** ([`int`](https://docs.python.org/3/builtins/functions.html#int) | [`None`](https://docs.python.org/3/builtins/constants.html#None)) – Number of retries attempted before failure
  * **original_error** ([`Exception`](https://docs.python.org/3/builtins/exceptions.html#Exception) | [`None`](https://docs.python.org/3/builtins/constants.html#None)) – The underlying exception that caused the failure

### *exception* contextgem.public.exceptions.ModelExtractionError(message, retry_count=None, original_error=None)

Bases: [`ContextGemError`](#contextgem.public.exceptions.ContextGemError)

Exception raised by the extraction methods when a model returns data that cannot
be used, and there is no fallback model left to try.

This is the case when:

- the response of an LLM cannot be parsed or validated, also after the LLM
  was asked again `max_retries_invalid_data` times;
- the response of a decision model cannot be used, e.g. the model refused
  to answer a question of a concept. A decision model is not asked again.

If `raise_exception_on_extraction_error=False` is passed to the extraction
method, a warning is logged instead.

Can be imported from `contextgem`.

* **Variables:**
  * **message** ([*str*](https://docs.python.org/3/builtins/stdtypes.html#str)) – Human-readable error description
  * **retry_count** ([*int*](https://docs.python.org/3/builtins/functions.html#int) *or* *None*) – Number of times that the model the error is for, i.e. the last
    model that was tried, was called again after it returned invalid data.
    The first call of the model, also of a fallback model, is not counted.
  * **original_error** ([*Exception*](https://docs.python.org/3/builtins/exceptions.html#Exception) *or* *None*) – The underlying exception that caused the failure
* **Parameters:**
  * **message** ([*str*](https://docs.python.org/3/builtins/stdtypes.html#str))
  * **retry_count** ([*int*](https://docs.python.org/3/builtins/functions.html#int) *|* *None*)
  * **original_error** ([*Exception*](https://docs.python.org/3/builtins/exceptions.html#Exception) *|* *None*)

Initialize the exception.

* **Parameters:**
  * **message** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Human-readable error description
  * **retry_count** ([`int`](https://docs.python.org/3/builtins/functions.html#int) | [`None`](https://docs.python.org/3/builtins/constants.html#None)) – Number of retries attempted before failure
  * **original_error** ([`Exception`](https://docs.python.org/3/builtins/exceptions.html#Exception) | [`None`](https://docs.python.org/3/builtins/constants.html#None)) – The underlying exception that caused the failure

### *exception* contextgem.public.exceptions.LLMToolLoopLimitError(message, retry_count=None, original_error=None)

Bases: [`ContextGemError`](#contextgem.public.exceptions.ContextGemError)

Exception raised from a chat when the tool-calling loop reaches the configured
`tool_max_rounds` limit and the LLM continues requesting tools.

Typically indicates that the LLM is stuck in a loop or needs more rounds to
complete the workflow. Consider increasing `tool_max_rounds` or adjusting
the tool instructions or the tool choice.

Can be imported from `contextgem`.

Initialize the exception.

* **Parameters:**
  * **message** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Human-readable error description
  * **retry_count** ([`int`](https://docs.python.org/3/builtins/functions.html#int) | [`None`](https://docs.python.org/3/builtins/constants.html#None)) – Number of retries attempted before failure
  * **original_error** ([`Exception`](https://docs.python.org/3/builtins/exceptions.html#Exception) | [`None`](https://docs.python.org/3/builtins/constants.html#None)) – The underlying exception that caused the failure

### *exception* contextgem.public.exceptions.ContextGemWarning

Bases: [`UserWarning`](https://docs.python.org/3/builtins/exceptions.html#UserWarning)

Category of the warnings that the framework issues for something in the calling
code that will not have the expected effect, e.g. tools set on an LLM that is
used for extraction, or an output language set together with a custom system
message. Such a warning is attributed to the line of the calling code that
caused it, where possible.

The warnings are Python warnings, not log messages, i.e. the logging level does
not affect them. To filter them, use this category, e.g.
`warnings.filterwarnings("ignore", category=ContextGemWarning)`, or make them
errors, e.g. in the tests of the calling code: a filter by the module of
the framework does not match a warning attributed to the calling code.
What happens while the framework runs, e.g. an extraction that fails when
`raise_exception_on_extraction_error=False` is passed to the extraction
method, is logged instead.

Can be imported from `contextgem`.
