Skip to content

Commit 0369437

Browse files
authored
Merge pull request #15 from UiPath/fix/handle_schema_exceptions
fix: handle schema exceptions
2 parents 1ebadba + c7b337f commit 0369437

File tree

4 files changed

+38
-24
lines changed

4 files changed

+38
-24
lines changed

pyproject.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
[project]
22
name = "uipath-dev"
3-
version = "0.0.5"
3+
version = "0.0.6"
44
description = "UiPath Developer Console"
55
readme = { file = "README.md", content-type = "text/markdown" }
66
requires-python = ">=3.11"
77
dependencies = [
8-
"uipath-runtime>=0.0.15, <0.1.0",
8+
"uipath-runtime>=0.0.21, <0.1.0",
99
"textual>=6.6.0, <7.0.0",
1010
"pyperclip>=1.11.0, <2.0.0",
1111
]

src/uipath/dev/_demo/mock_runtime.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ async def new_runtime(
4545
)
4646
return MockGreetingRuntime(entrypoint=entrypoint)
4747

48-
def discover_runtimes(self) -> list[UiPathRuntimeProtocol]:
48+
async def discover_runtimes(self) -> list[UiPathRuntimeProtocol]:
4949
"""Return prototype instances for discovery (not really used by the UI)."""
5050
return [
5151
MockGreetingRuntime(entrypoint=ENTRYPOINT_GREETING),
@@ -62,3 +62,7 @@ def discover_entrypoints(self) -> list[str]:
6262
ENTRYPOINT_ANALYZE_NUMBERS,
6363
ENTRYPOINT_SUPPORT_CHAT,
6464
]
65+
66+
async def dispose(self) -> None:
67+
"""Dispose of any resources (no-op for mock)."""
68+
pass

src/uipath/dev/ui/panels/new_run_panel.py

Lines changed: 26 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
from textual.app import ComposeResult
77
from textual.containers import Container, Horizontal, Vertical
88
from textual.reactive import reactive
9-
from textual.widgets import Button, Select, TabbedContent, TabPane, TextArea
9+
from textual.widgets import Button, Select, TabbedContent, TabPane
1010
from uipath.runtime import UiPathRuntimeFactoryProtocol, UiPathRuntimeProtocol
1111

1212
from uipath.dev.ui.widgets.json_input import JsonInput
@@ -149,7 +149,7 @@ async def on_mount(self) -> None:
149149

150150
select = self.query_one("#entrypoint-select", Select)
151151

152-
json_input = self.query_one("#json-input", TextArea)
152+
json_input = self.query_one("#json-input", JsonInput)
153153
run_button = self.query_one("#execute-btn", Button)
154154

155155
if not self.entrypoints:
@@ -166,14 +166,17 @@ async def on_mount(self) -> None:
166166

167167
# Use the first entrypoint as default
168168
self.selected_entrypoint = self.entrypoints[0]
169-
select.value = self.selected_entrypoint
170169

171-
# Lazily fetch schema and populate input
170+
# Lazily fetch schema and populate input BEFORE setting select.value
171+
# to avoid triggering on_select_changed
172172
await self._load_schema_and_update_input(self.selected_entrypoint)
173173

174+
# Set the select value after loading the schema
175+
select.value = self.selected_entrypoint
176+
174177
async def _load_schema_and_update_input(self, entrypoint: str) -> None:
175178
"""Ensure schema for entrypoint is loaded, then update JSON input."""
176-
json_input = self.query_one("#json-input", TextArea)
179+
json_input = self.query_one("#json-input", JsonInput)
177180

178181
if not entrypoint or entrypoint == "no-entrypoints":
179182
json_input.text = "{}"
@@ -192,33 +195,40 @@ async def _load_schema_and_update_input(self, entrypoint: str) -> None:
192195
input_schema = schema_obj.input or {}
193196
self.entrypoint_schemas[entrypoint] = input_schema
194197
schema = input_schema
195-
except Exception:
196-
schema = {}
197-
self.entrypoint_schemas[entrypoint] = schema
198+
except Exception as e:
199+
json_input.text = "{}"
200+
self.app.notify(
201+
f"Error loading schema for '{entrypoint}': {str(e)}",
202+
severity="error",
203+
timeout=5,
204+
)
205+
return
198206
finally:
199207
if runtime is not None:
200208
await runtime.dispose()
201209

202-
json_input.text = json.dumps(
203-
mock_json_from_schema(schema),
204-
indent=2,
205-
)
210+
# Generate mock JSON from schema
211+
mock_data = mock_json_from_schema(schema)
212+
json_input.text = json.dumps(mock_data, indent=2)
206213

207214
async def on_select_changed(self, event: Select.Changed) -> None:
208215
"""Update JSON input when user selects an entrypoint."""
209-
self.selected_entrypoint = cast(str, event.value) if event.value else ""
216+
new_entrypoint = cast(str, event.value) if event.value else ""
210217

211-
await self._load_schema_and_update_input(self.selected_entrypoint)
218+
# Only load schema if the entrypoint actually changed
219+
if new_entrypoint != self.selected_entrypoint:
220+
self.selected_entrypoint = new_entrypoint
221+
await self._load_schema_and_update_input(self.selected_entrypoint)
212222

213223
def get_input_values(self) -> Tuple[str, str, bool]:
214224
"""Get the selected entrypoint and JSON input values."""
215-
json_input = self.query_one("#json-input", TextArea)
225+
json_input = self.query_one("#json-input", JsonInput)
216226
return self.selected_entrypoint, json_input.text.strip(), self.conversational
217227

218228
def reset_form(self) -> None:
219229
"""Reset selection and JSON input to defaults."""
220230
select = self.query_one("#entrypoint-select", Select)
221-
json_input = self.query_one("#json-input", TextArea)
231+
json_input = self.query_one("#json-input", JsonInput)
222232

223233
if not self.entrypoints:
224234
self.selected_entrypoint = ""

uv.lock

Lines changed: 5 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)