Skip to content

Commit 518d975

Browse files
authored
improve error message for untyped vars (#4963)
1 parent f69f420 commit 518d975

File tree

4 files changed

+60
-7
lines changed

4 files changed

+60
-7
lines changed

reflex/components/core/foreach.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -100,8 +100,9 @@ def create(
100100
component.children = [component._render().render_component()]
101101
except UntypedVarError as e:
102102
raise UntypedVarError(
103-
f"Could not foreach over var `{iterable!s}` without a type annotation. "
104-
"See https://reflex.dev/docs/library/dynamic-rendering/foreach/"
103+
iterable,
104+
"foreach",
105+
"https://reflex.dev/docs/library/dynamic-rendering/foreach/",
105106
) from e
106107
return component
107108

reflex/state.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1013,9 +1013,9 @@ def _init_var(cls, prop: Var):
10131013

10141014
if not types.is_valid_var_type(prop._var_type):
10151015
raise VarTypeError(
1016-
"State vars must be primitive Python types, "
1017-
"Plotly figures, Pandas dataframes, "
1018-
"or subclasses of rx.Base. "
1016+
"State vars must be of a serializable type. "
1017+
"Valid types include strings, numbers, booleans, lists, "
1018+
"dictionaries, dataclasses, datetime objects, and pydantic models. "
10191019
f'Found var "{prop._js_expr}" with type {prop._var_type}.'
10201020
)
10211021
cls._set_var(prop)

reflex/utils/exceptions.py

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
"""Custom Exceptions."""
22

3-
from typing import Any
3+
from __future__ import annotations
4+
5+
from typing import TYPE_CHECKING, Any
6+
7+
if TYPE_CHECKING:
8+
from reflex.vars import Var
49

510

611
class ReflexError(Exception):
@@ -78,6 +83,31 @@ class VarAttributeError(ReflexError, AttributeError):
7883
class UntypedVarError(ReflexError, TypeError):
7984
"""Custom TypeError for untyped var errors."""
8085

86+
def __init__(self, var: Var, action: str, doc_link: str = ""):
87+
"""Create an UntypedVarError from a var.
88+
89+
Args:
90+
var: The var.
91+
action: The action that caused the error.
92+
doc_link: The link to the documentation.
93+
"""
94+
var_data = var._get_all_var_data()
95+
is_state_var = (
96+
var_data
97+
and var_data.state
98+
and var_data.field_name
99+
and var_data.state + "." + var_data.field_name == str(var)
100+
)
101+
super().__init__(
102+
f"Cannot {action} on untyped var '{var!s}' of type '{var._var_type!s}'."
103+
+ (
104+
" Please add a type annotation to the var in the state class."
105+
if is_state_var
106+
else " You can call the var's .to(desired_type) method to convert it to the desired type."
107+
)
108+
+ (f" See {doc_link}" if doc_link else "")
109+
)
110+
81111

82112
class UntypedComputedVarError(ReflexError, TypeError):
83113
"""Custom TypeError for untyped computed var errors."""

reflex/vars/base.py

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1256,6 +1256,27 @@ def range(
12561256

12571257
if not TYPE_CHECKING:
12581258

1259+
def __getitem__(self, key: Any) -> Var:
1260+
"""Get the item from the var.
1261+
1262+
Args:
1263+
key: The key to get.
1264+
1265+
Raises:
1266+
UntypedVarError: If the var type is Any.
1267+
TypeError: If the var type is Any.
1268+
1269+
# noqa: DAR101 self
1270+
"""
1271+
if self._var_type is Any:
1272+
raise exceptions.UntypedVarError(
1273+
self,
1274+
f"access the item '{key}'",
1275+
)
1276+
raise TypeError(
1277+
f"Var of type {self._var_type} does not support item access."
1278+
)
1279+
12591280
def __getattr__(self, name: str):
12601281
"""Get an attribute of the var.
12611282
@@ -1281,7 +1302,8 @@ def __getattr__(self, name: str):
12811302

12821303
if self._var_type is Any:
12831304
raise exceptions.UntypedVarError(
1284-
f"You must provide an annotation for the state var `{self!s}`. Annotation cannot be `{self._var_type}`."
1305+
self,
1306+
f"access the attribute '{name}'",
12851307
)
12861308

12871309
raise VarAttributeError(

0 commit comments

Comments
 (0)