Skip to content

Commit 79251a4

Browse files
authored
Merge pull request #36 from UiPath/fix/graceful_debug_termination
fix: graceful debug termination
2 parents 101b747 + d464d05 commit 79251a4

File tree

4 files changed

+21
-27
lines changed

4 files changed

+21
-27
lines changed

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[project]
22
name = "uipath-runtime"
3-
version = "0.0.23"
3+
version = "0.1.0"
44
description = "Runtime abstractions and interfaces for building agents and automation scripts in the UiPath ecosystem"
55
readme = { file = "README.md", content-type = "text/markdown" }
66
requires-python = ">=3.11"

src/uipath/runtime/debug/bridge.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,10 @@ async def wait_for_resume(self) -> Any:
5555
"""Wait for resume command from debugger."""
5656
...
5757

58+
async def wait_for_terminate(self) -> None:
59+
"""Wait until the user has requested to terminate debugging."""
60+
...
61+
5862
def get_breakpoints(self) -> list[str] | Literal["*"]:
5963
"""Get nodes to suspend execution at.
6064

src/uipath/runtime/debug/runtime.py

Lines changed: 15 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -251,36 +251,32 @@ async def _poll_trigger(
251251
while True:
252252
attempt += 1
253253

254-
await self.debug_bridge.emit_state_update(
255-
UiPathRuntimeStateEvent(
256-
node_name="<polling>",
257-
payload={
258-
"status": "polling",
259-
"attempt": attempt,
260-
},
261-
)
262-
)
263-
264254
try:
265255
resume_data = await reader.read_trigger(trigger)
266256

267257
if resume_data is not None:
268258
return resume_data
269259

260+
await self.debug_bridge.emit_state_update(
261+
UiPathRuntimeStateEvent(
262+
node_name="<polling>",
263+
payload={
264+
"attempt": attempt,
265+
},
266+
)
267+
)
268+
270269
await self._wait_with_quit_check()
271270

272271
except UiPathDebugQuitError:
273-
logger.info("Quit requested during polling")
274272
raise
275273
except Exception as e:
276-
logger.error(f"Error polling trigger: {e}", exc_info=True)
277274
await self.debug_bridge.emit_state_update(
278275
UiPathRuntimeStateEvent(
279276
node_name="<polling>",
280277
payload={
281-
"status": "poll_error",
282278
"attempt": attempt,
283-
"error": str(e),
279+
"info": str(e),
284280
},
285281
)
286282
)
@@ -294,25 +290,19 @@ async def _wait_with_quit_check(self) -> None:
294290
UiPathDebugQuitError: If quit is requested during wait
295291
"""
296292
sleep_task = asyncio.create_task(asyncio.sleep(self.trigger_poll_interval))
297-
resume_task = asyncio.create_task(self.debug_bridge.wait_for_resume())
293+
term_task = asyncio.create_task(self.debug_bridge.wait_for_terminate())
298294

299295
done, pending = await asyncio.wait(
300-
{sleep_task, resume_task}, return_when=asyncio.FIRST_COMPLETED
296+
{sleep_task, term_task},
297+
return_when=asyncio.FIRST_COMPLETED,
301298
)
302299

303300
for task in pending:
304301
task.cancel()
305302
try:
306303
await task
307304
except asyncio.CancelledError:
308-
# Expected when cancelling pending tasks; safe to ignore.
309305
pass
310306

311-
# Check if quit was triggered
312-
if resume_task in done:
313-
try:
314-
await (
315-
resume_task
316-
) # This will raise UiPathDebugQuitError if it was a quit
317-
except UiPathDebugQuitError:
318-
raise
307+
if term_task in done:
308+
raise UiPathDebugQuitError("Debugging terminated during polling.")

uv.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)