Skip to content

Commit 5398636

Browse files
redesigned context-not-available error to follow the same principles as other IQL errors, inherting from IQLError, thus enabled its handling by self-reflection mechanism
1 parent 273e217 commit 5398636

File tree

3 files changed

+41
-34
lines changed

3 files changed

+41
-34
lines changed

src/dbally/context/exceptions.py

-21
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,5 @@
1-
from abc import ABC
2-
3-
4-
class BaseContextException(Exception, ABC):
5-
"""
6-
A base (abstract) exception for all specification context-related exception.
7-
"""
8-
9-
101
class ContextNotAvailableError(Exception):
112
"""
123
An exception inheriting from BaseContextException pointining that no sufficient context information
134
was provided by the user while calling view.ask().
145
"""
15-
16-
17-
class ContextualisationNotAllowed(Exception):
18-
"""
19-
An exception inheriting from BaseContextException pointining that the filter method signature
20-
does not allow to provide an additional context.
21-
"""
22-
23-
24-
# WORKAROUND - traditional inhertiance syntax is not working in context of abstract Exceptions
25-
BaseContextException.register(ContextNotAvailableError)
26-
BaseContextException.register(ContextualisationNotAllowed)

src/dbally/iql/_exceptions.py

+38-4
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,26 @@
11
import ast
22
from typing import Optional, Union
33

4+
from typing_extensions import TypeAlias
5+
46
from dbally.exceptions import DbAllyError
57

8+
IQLNode: TypeAlias = Union[ast.stmt, ast.expr]
9+
610

711
class IQLError(DbAllyError):
8-
"""Base exception for all IQL parsing related exceptions."""
12+
"""
13+
Base exception for all IQL parsing related exceptions.
14+
15+
Attributes:
16+
node: An IQL Node (AST Exprresion) during which processing an error was encountered.
17+
source: Raw LLM response containing IQL filter calls.
18+
"""
19+
20+
node: IQLNode
21+
source: str
922

10-
def __init__(self, message: str, node: Union[ast.stmt, ast.expr], source: str) -> None:
23+
def __init__(self, message: str, node: IQLNode, source: str) -> None:
1124
message = message + ": " + source[node.col_offset : node.end_col_offset]
1225

1326
super().__init__(message)
@@ -18,15 +31,15 @@ def __init__(self, message: str, node: Union[ast.stmt, ast.expr], source: str) -
1831
class IQLArgumentParsingError(IQLError):
1932
"""Raised when an argument cannot be parsed into a valid IQL."""
2033

21-
def __init__(self, node: Union[ast.stmt, ast.expr], source: str) -> None:
34+
def __init__(self, node: IQLNode, source: str) -> None:
2235
message = "Not a valid IQL argument"
2336
super().__init__(message, node, source)
2437

2538

2639
class IQLUnsupportedSyntaxError(IQLError):
2740
"""Raised when trying to parse an unsupported syntax."""
2841

29-
def __init__(self, node: Union[ast.stmt, ast.expr], source: str, context: Optional[str] = None) -> None:
42+
def __init__(self, node: IQLNode, source: str, context: Optional[str] = None) -> None:
3043
node_name = node.__class__.__name__
3144

3245
message = f"{node_name} syntax is not supported in IQL"
@@ -47,3 +60,24 @@ def __init__(self, node: ast.Name, source: str) -> None:
4760

4861
class IQLArgumentValidationError(IQLError):
4962
"""Raised when argument is not valid for a given method."""
63+
64+
65+
class IQLContextNotAllowedError(IQLError):
66+
"""
67+
Raised when a context call/keyword has been passed as an argument to the filter
68+
which does not support contextualization for this specific parameter.
69+
"""
70+
71+
def __init__(self, node: IQLNode, source: str, arg_name: Optional[str] = None) -> None:
72+
if arg_name is None:
73+
message = (
74+
"The LLM detected that the context is required to execute the query"
75+
"while the filter signature does not allow it at all."
76+
)
77+
else:
78+
message = (
79+
"The LLM detected that the context is required to execute the query"
80+
f"while the filter signature does allow it for `{arg_name}` argument."
81+
)
82+
83+
super().__init__(message, node, source)

src/dbally/iql/_processor.py

+3-9
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,11 @@
44
from dbally.audit.event_tracker import EventTracker
55
from dbally.context._utils import _does_arg_allow_context
66
from dbally.context.context import BaseCallerContext, CustomContext
7-
from dbally.context.exceptions import ContextualisationNotAllowed
87
from dbally.iql import syntax
98
from dbally.iql._exceptions import (
109
IQLArgumentParsingError,
1110
IQLArgumentValidationError,
11+
IQLContextNotAllowedError,
1212
IQLError,
1313
IQLFunctionNotExists,
1414
IQLUnsupportedSyntaxError,
@@ -143,16 +143,10 @@ def _parse_arg(
143143
raise IQLArgumentParsingError(arg, self.source)
144144

145145
if parent_func_def.context_class is None:
146-
raise ContextualisationNotAllowed(
147-
"The LLM detected that the context is required +\
148-
to execute the query while the filter signature does not allow it at all."
149-
)
146+
raise IQLContextNotAllowedError(arg, self.source)
150147

151148
if not _does_arg_allow_context(arg_spec):
152-
raise ContextualisationNotAllowed(
153-
f"The LLM detected that the context is required +\
154-
to execute the query while the filter signature does allow it for `{arg_spec.name}` argument."
155-
)
149+
raise IQLContextNotAllowedError(arg, self.source, arg_name=arg_spec.name)
156150

157151
return parent_func_def.context_class.select_context(self.contexts)
158152

0 commit comments

Comments
 (0)