Skip to content

Commit c28d0cc

Browse files
committed
chore: add missing runtime status
1 parent e824efd commit c28d0cc

File tree

7 files changed

+58
-14
lines changed

7 files changed

+58
-14
lines changed

pyproject.toml

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
[project]
22
name = "uipath-runtime"
3-
version = "0.1.2"
3+
version = "0.1.3"
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"
77
dependencies = [
8-
"uipath-core>=0.0.5, <0.1.0",
8+
"uipath-core==0.0.7.dev1000110062",
99
]
1010
classifiers = [
1111
"Intended Audience :: Developers",
@@ -106,3 +106,6 @@ name = "testpypi"
106106
url = "https://test.pypi.org/simple/"
107107
publish-url = "https://test.pypi.org/legacy/"
108108
explicit = true
109+
110+
[tool.uv.sources]
111+
uipath-core = { index = "testpypi" }

src/uipath/runtime/debug/runtime.py

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
import logging
55
from typing import Any, AsyncGenerator, cast
66

7+
from uipath.core.exceptions import UiPathResumeTriggerException, UiPathResumeTriggerPendingException
8+
79
from uipath.runtime.base import (
810
UiPathExecuteOptions,
911
UiPathRuntimeProtocol,
@@ -15,6 +17,8 @@
1517
UiPathDebugBridgeProtocol,
1618
UiPathDebugQuitError,
1719
)
20+
from uipath.runtime.errors import UiPathRuntimeError, UiPathErrorCode
21+
from uipath.runtime.errors.exception import handle_runtime_exceptions
1822
from uipath.runtime.events import (
1923
UiPathRuntimeEvent,
2024
UiPathRuntimeStateEvent,
@@ -54,6 +58,7 @@ def __init__(
5458
raise ValueError("trigger_poll_interval must be >= 0")
5559
self.trigger_poll_interval = trigger_poll_interval
5660

61+
@handle_runtime_exceptions
5762
async def execute(
5863
self,
5964
input: dict[str, Any] | None = None,
@@ -71,6 +76,7 @@ async def execute(
7176
else UiPathRuntimeResult(status=UiPathRuntimeStatus.SUCCESSFUL)
7277
)
7378

79+
@handle_runtime_exceptions
7480
async def stream(
7581
self,
7682
input: dict[str, Any] | None = None,
@@ -271,9 +277,14 @@ async def _poll_trigger(
271277

272278
await self._wait_with_quit_check()
273279

274-
except UiPathDebugQuitError:
280+
except (UiPathDebugQuitError):
275281
raise
276-
except Exception as e:
282+
283+
except UiPathResumeTriggerException as e:
284+
if not isinstance(e, UiPathResumeTriggerPendingException):
285+
raise UiPathRuntimeError.from_resume_trigger_exception(e)
286+
287+
# trigger still pending
277288
await self.debug_bridge.emit_state_update(
278289
UiPathRuntimeStateEvent(
279290
node_name="<polling>",
@@ -284,7 +295,7 @@ async def _poll_trigger(
284295
)
285296
)
286297

287-
await self._wait_with_quit_check()
298+
await self._wait_with_quit_check()
288299

289300
async def _wait_with_quit_check(self) -> None:
290301
"""Wait for specified seconds, but allow quit command to interrupt.

src/uipath/runtime/errors/codes.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ class UiPathErrorCode(str, Enum):
2424
INPUT_INVALID_JSON = "INPUT_INVALID_JSON"
2525

2626
# HITL (Human-In-The-Loop) related errors
27+
RESUME_TRIGGER_ERROR = "RESUME_TRIGGER_ERROR"
2728
INVOKED_PROCESS_FAILURE = "INVOKED_PROCESS_FAILURE"
2829
CREATE_RESUME_TRIGGER_ERROR = "CREATE_RESUME_TRIGGER_ERROR"
2930
RETRIEVE_RESUME_TRIGGER_ERROR = "RETRIEVE_PAYLOAD_ERROR"

src/uipath/runtime/errors/exception.py

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,10 @@
22

33
import sys
44
import traceback
5-
from typing import Any
5+
from functools import wraps
6+
from typing import Any, Callable
7+
8+
from uipath.core.exceptions import UiPathResumeTriggerException
69

710
from uipath.runtime.errors.codes import UiPathErrorCode
811
from uipath.runtime.errors.contract import UiPathErrorCategory, UiPathErrorContract
@@ -99,3 +102,21 @@ def __init__(
99102
prefix=prefix,
100103
include_traceback=include_traceback,
101104
)
105+
106+
@classmethod
107+
def from_resume_trigger_exception(cls, exc: UiPathResumeTriggerException) -> "UiPathRuntimeError":
108+
return cls(
109+
code=UiPathErrorCode.RESUME_TRIGGER_ERROR,
110+
title="Resume trigger error",
111+
detail=exc.message,
112+
)
113+
114+
def handle_runtime_exceptions(func: Callable[..., Any]) -> Callable[..., Any]:
115+
@wraps(func)
116+
async def wrapper(*args, **kwargs):
117+
try:
118+
return await func(*args, **kwargs)
119+
except UiPathResumeTriggerException as e:
120+
raise UiPathRuntimeError.from_resume_trigger_exception(e)
121+
122+
return wrapper

src/uipath/runtime/result.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ class UiPathRuntimeStatus(str, Enum):
1717
FAULTED = "faulted"
1818
SUSPENDED = "suspended"
1919

20-
2120
class UiPathRuntimeResult(UiPathRuntimeEvent):
2221
"""Result of an execution with status and optional error information."""
2322

src/uipath/runtime/resumable/runtime.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,16 @@
33
import logging
44
from typing import Any, AsyncGenerator
55

6+
from uipath.core.exceptions import UiPathResumeTriggerException
7+
68
from uipath.runtime.base import (
79
UiPathExecuteOptions,
810
UiPathRuntimeProtocol,
911
UiPathStreamOptions,
1012
)
1113
from uipath.runtime.debug import UiPathBreakpointResult
14+
from uipath.runtime.errors import UiPathRuntimeError
15+
from uipath.runtime.errors.exception import handle_runtime_exceptions
1216
from uipath.runtime.events import UiPathRuntimeEvent
1317
from uipath.runtime.result import UiPathRuntimeResult, UiPathRuntimeStatus
1418
from uipath.runtime.resumable.protocols import (
@@ -47,6 +51,7 @@ def __init__(
4751
self.storage = storage
4852
self.trigger_manager = trigger_manager
4953

54+
@handle_runtime_exceptions
5055
async def execute(
5156
self,
5257
input: dict[str, Any] | None = None,
@@ -66,11 +71,15 @@ async def execute(
6671
input = await self._restore_resume_input(input)
6772

6873
# Execute the delegate
69-
result = await self.delegate.execute(input, options=options)
74+
try:
75+
result = await self.delegate.execute(input, options=options)
76+
except UiPathResumeTriggerException as e:
77+
raise UiPathRuntimeError.from_resume_trigger_exception(e)
7078

7179
# If suspended, create and persist trigger
7280
return await self._handle_suspension(result)
7381

82+
@handle_runtime_exceptions
7483
async def stream(
7584
self,
7685
input: dict[str, Any] | None = None,

uv.lock

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

0 commit comments

Comments
 (0)