Skip to content

Commit 90b0e66

Browse files
authored
refactor(iql): add iql gen exception (#77)
1 parent 0a22942 commit 90b0e66

File tree

6 files changed

+70
-11
lines changed

6 files changed

+70
-11
lines changed

src/dbally/iql_generator/iql_generator.py

+8-2
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
from dbally.iql_generator.prompt import IQL_GENERATION_TEMPLATE, IQLGenerationPromptFormat
66
from dbally.llms.base import LLM
77
from dbally.llms.clients.base import LLMOptions
8+
from dbally.llms.clients.exceptions import LLMError
89
from dbally.prompt.elements import FewShotExample
910
from dbally.prompt.template import PromptTemplate
1011
from dbally.views.exposed_functions import ExposedFunction
@@ -52,13 +53,15 @@ async def generate_iql(
5253
event_tracker: Event store used to audit the generation process.
5354
examples: List of examples to be injected into the conversation.
5455
llm_options: Options to use for the LLM client.
55-
n_retries: Number of retries to regenerate IQL in case of errors.
56+
n_retries: Number of retries to regenerate IQL in case of errors in parsing or LLM connection.
5657
5758
Returns:
5859
Generated IQL query.
5960
6061
Raises:
61-
IQLError: If IQL generation fails after all retries.
62+
LLMError: If LLM text generation fails after all retries.
63+
IQLError: If IQL parsing fails after all retries.
64+
UnsupportedQueryError: If the question is not supported by the view.
6265
"""
6366
prompt_format = IQLGenerationPromptFormat(
6467
question=question,
@@ -82,6 +85,9 @@ async def generate_iql(
8285
allowed_functions=filters,
8386
event_tracker=event_tracker,
8487
)
88+
except LLMError as exc:
89+
if retry == n_retries:
90+
raise exc
8591
except IQLError as exc:
8692
if retry == n_retries:
8793
raise exc

src/dbally/llms/base.py

+3
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,9 @@ async def generate_text(
6969
7070
Returns:
7171
Text response from LLM.
72+
73+
Raises:
74+
LLMError: If LLM text generation fails.
7275
"""
7376
options = (self.default_options | options) if options else self.default_options
7477
event = LLMEvent(prompt=prompt.chat, type=type(prompt).__name__)

src/dbally/nl_responder/nl_responder.py

+3
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,9 @@ async def generate_response(
5959
6060
Returns:
6161
Natural language response to the user question.
62+
63+
Raises:
64+
LLMError: If LLM text generation fails.
6265
"""
6366
prompt_format = NLResponsePromptFormat(
6467
question=question,

src/dbally/view_selection/llm_view_selector.py

+3
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,9 @@ async def select_view(
4848
4949
Returns:
5050
The most relevant view name.
51+
52+
Raises:
53+
LLMError: If LLM text generation fails.
5154
"""
5255
prompt_format = ViewSelectionPromptFormat(question=question, views=views)
5356
formatted_prompt = self._prompt_template.format_prompt(prompt_format)

src/dbally/views/exceptions.py

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
from typing import Optional
2+
3+
from dbally.exceptions import DbAllyError
4+
5+
6+
class IQLGenerationError(DbAllyError):
7+
"""
8+
Exception for when an error occurs while generating IQL for a view.
9+
"""
10+
11+
def __init__(
12+
self,
13+
view_name: str,
14+
filters: Optional[str] = None,
15+
aggregation: Optional[str] = None,
16+
) -> None:
17+
"""
18+
Args:
19+
view_name: Name of the view that caused the error.
20+
filters: Filters generated by the view.
21+
aggregation: Aggregation generated by the view.
22+
"""
23+
super().__init__(f"Error while generating IQL for view {view_name}")
24+
self.view_name = view_name
25+
self.filters = filters
26+
self.aggregation = aggregation

src/dbally/views/structured.py

+27-9
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,12 @@
55
from dbally.audit.event_tracker import EventTracker
66
from dbally.collection.results import ViewExecutionResult
77
from dbally.iql import IQLQuery
8+
from dbally.iql._exceptions import IQLError
89
from dbally.iql_generator.iql_generator import IQLGenerator
10+
from dbally.iql_generator.prompt import UnsupportedQueryError
911
from dbally.llms.base import LLM
1012
from dbally.llms.clients.base import LLMOptions
13+
from dbally.views.exceptions import IQLGenerationError
1114
from dbally.views.exposed_functions import ExposedFunction
1215

1316
from ..similarity import AbstractSimilarityIndex
@@ -57,21 +60,36 @@ async def ask(
5760
The result of the query.
5861
5962
Raises:
60-
IQLError: If the generated IQL query is not valid.
63+
LLMError: If LLM text generation API fails.
64+
IQLGenerationError: If the IQL generation fails.
6165
"""
6266
iql_generator = self.get_iql_generator(llm)
6367

6468
filters = self.list_filters()
6569
examples = self.list_few_shots()
6670

67-
iql = await iql_generator.generate_iql(
68-
question=query,
69-
filters=filters,
70-
examples=examples,
71-
event_tracker=event_tracker,
72-
llm_options=llm_options,
73-
n_retries=n_retries,
74-
)
71+
try:
72+
iql = await iql_generator.generate_iql(
73+
question=query,
74+
filters=filters,
75+
examples=examples,
76+
event_tracker=event_tracker,
77+
llm_options=llm_options,
78+
n_retries=n_retries,
79+
)
80+
except UnsupportedQueryError as exc:
81+
raise IQLGenerationError(
82+
view_name=self.__class__.__name__,
83+
filters=None,
84+
aggregation=None,
85+
) from exc
86+
except IQLError as exc:
87+
raise IQLGenerationError(
88+
view_name=self.__class__.__name__,
89+
filters=exc.source,
90+
aggregation=None,
91+
) from exc
92+
7593
await self.apply_filters(iql)
7694

7795
result = self.execute(dry_run=dry_run)

0 commit comments

Comments
 (0)