Skip to content

Commit 096f260

Browse files
committed
feat(error_code): added error code as enum
1 parent dbffd67 commit 096f260

4 files changed

Lines changed: 58 additions & 23 deletions

File tree

src/uipath/_cli/_runtime/_contracts.py

Lines changed: 40 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,40 @@ class UiPathErrorCategory(str, Enum):
7979
USER = "User" # Business logic or domain-level errors
8080

8181

82+
class UiPathErrorCode(str, Enum):
83+
"""Standard error codes for UiPath runtime errors."""
84+
85+
# Entrypoint related errors
86+
ENTRYPOINT_MISSING = "ENTRYPOINT_MISSING"
87+
ENTRYPOINT_NOT_FOUND = "ENTRYPOINT_NOT_FOUND"
88+
ENTRYPOINT_FUNCTION_MISSING = "ENTRYPOINT_FUNCTION_MISSING"
89+
90+
# Module and execution errors
91+
IMPORT_ERROR = "IMPORT_ERROR"
92+
MODULE_EXECUTION_ERROR = "MODULE_EXECUTION_ERROR"
93+
FUNCTION_EXECUTION_ERROR = "FUNCTION_EXECUTION_ERROR"
94+
EXECUTION_ERROR = "EXECUTION_ERROR"
95+
96+
# Input validation errors
97+
INVALID_INPUT_FILE_EXTENSION = "INVALID_INPUT_FILE_EXTENSION"
98+
INPUT_INVALID_JSON = "INPUT_INVALID_JSON"
99+
100+
# Process and job related errors
101+
INVOKED_PROCESS_FAILURE = "INVOKED_PROCESS_FAILURE"
102+
API_CONNECTION_ERROR = "API_CONNECTION_ERROR"
103+
104+
# HITL (Human-In-The-Loop) related errors
105+
HITL_FEEDBACK_FAILURE = "HITL_FEEDBACK_FAILURE"
106+
UNKNOWN_HITL_MODEL = "UNKNOWN_HITL_MODEL"
107+
HITL_ACTION_CREATION_FAILED = "HITL_ACTION_CREATION_FAILED"
108+
109+
# Trigger type errors
110+
UNKNOWN_TRIGGER_TYPE = "UNKNOWN_TRIGGER_TYPE"
111+
112+
# Runtime shutdown errors
113+
RUNTIME_SHUTDOWN_ERROR = "RUNTIME_SHUTDOWN_ERROR"
114+
115+
82116
class UiPathErrorContract(BaseModel):
83117
"""Standard error contract used across the runtime."""
84118

@@ -400,7 +434,7 @@ class UiPathRuntimeError(Exception):
400434

401435
def __init__(
402436
self,
403-
code: str,
437+
code: UiPathErrorCode,
404438
title: str,
405439
detail: str,
406440
category: UiPathErrorCategory = UiPathErrorCategory.UNKNOWN,
@@ -419,8 +453,10 @@ def __init__(
419453
if status is None:
420454
status = self._extract_http_status()
421455

456+
code_value = code.value
457+
422458
self.error_info = UiPathErrorContract(
423-
code=f"{prefix}.{code}",
459+
code=f"{prefix}.{code_value}",
424460
title=title,
425461
detail=detail,
426462
category=category,
@@ -497,7 +533,7 @@ async def __aenter__(self):
497533
_, file_extension = os.path.splitext(self.context.input_file)
498534
if file_extension != ".json":
499535
raise UiPathRuntimeError(
500-
code="INVALID_INPUT_FILE_EXTENSION",
536+
code=UiPathErrorCode.INVALID_INPUT_FILE_EXTENSION,
501537
title="Invalid Input File Extension",
502538
detail="The provided input file must be in JSON format.",
503539
)
@@ -511,7 +547,7 @@ async def __aenter__(self):
511547
self.context.input_json = {}
512548
except json.JSONDecodeError as e:
513549
raise UiPathRuntimeError(
514-
"INPUT_INVALID_JSON",
550+
UiPathErrorCode.INPUT_INVALID_JSON,
515551
"Invalid JSON input",
516552
f"The input data is not valid JSON: {str(e)}",
517553
UiPathErrorCategory.USER,

src/uipath/_cli/_runtime/_hitl.py

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
from .._runtime._contracts import (
1111
UiPathApiTrigger,
1212
UiPathErrorCategory,
13+
UiPathErrorCode,
1314
UiPathResumeTrigger,
1415
UiPathResumeTriggerType,
1516
UiPathRuntimeError,
@@ -87,7 +88,7 @@ async def read(cls, resume_trigger: UiPathResumeTrigger) -> Optional[str]:
8788
== UiPathRuntimeStatus.SUCCESSFUL.value.lower()
8889
):
8990
raise UiPathRuntimeError(
90-
"INVOKED_PROCESS_FAILURE",
91+
UiPathErrorCode.INVOKED_PROCESS_FAILURE,
9192
"Invoked process did not finish successfully.",
9293
_try_convert_to_json_format(str(job.job_error or job.info))
9394
or "Job error unavailable.",
@@ -103,21 +104,21 @@ async def read(cls, resume_trigger: UiPathResumeTrigger) -> Optional[str]:
103104
)
104105
except Exception as e:
105106
raise UiPathRuntimeError(
106-
"API_CONNECTION_ERROR",
107+
UiPathErrorCode.API_CONNECTION_ERROR,
107108
"Failed to get trigger payload",
108109
f"Error fetching API trigger payload for inbox {resume_trigger.api_resume.inbox_id}: {str(e)}",
109110
UiPathErrorCategory.SYSTEM,
110111
) from e
111112
case _:
112113
raise UiPathRuntimeError(
113-
"UNKNOWN_TRIGGER_TYPE",
114+
UiPathErrorCode.UNKNOWN_TRIGGER_TYPE,
114115
"Unexpected trigger type received",
115116
f"Trigger type :{type(resume_trigger.trigger_type)} is invalid",
116117
UiPathErrorCategory.USER,
117118
)
118119

119120
raise UiPathRuntimeError(
120-
"HITL_FEEDBACK_FAILURE",
121+
UiPathErrorCode.HITL_FEEDBACK_FAILURE,
121122
"Failed to receive payload from HITL action",
122123
detail="Failed to receive payload from HITL action",
123124
category=UiPathErrorCategory.SYSTEM,
@@ -242,14 +243,14 @@ async def create_resume_trigger(self) -> UiPathResumeTrigger:
242243
)
243244
case _:
244245
raise UiPathRuntimeError(
245-
"UNKNOWN_HITL_MODEL",
246+
UiPathErrorCode.UNKNOWN_HITL_MODEL,
246247
"Unexpected model received",
247248
f"{type(hitl_input)} is not a valid Human(Robot/Agent)-In-The-Loop model",
248249
UiPathErrorCategory.USER,
249250
)
250251
except Exception as e:
251252
raise UiPathRuntimeError(
252-
"HITL_ACTION_CREATION_FAILED",
253+
UiPathErrorCode.HITL_ACTION_CREATION_FAILED,
253254
"Failed to create HITL action",
254255
f"{str(e)}",
255256
UiPathErrorCategory.SYSTEM,

src/uipath/_cli/_runtime/_runtime.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
from ._contracts import (
77
UiPathBaseRuntime,
88
UiPathErrorCategory,
9+
UiPathErrorCode,
910
UiPathRuntimeContext,
1011
UiPathRuntimeError,
1112
UiPathRuntimeResult,
@@ -59,7 +60,7 @@ async def execute(self) -> Optional[UiPathRuntimeResult]:
5960
raise
6061

6162
raise UiPathRuntimeError(
62-
"EXECUTION_ERROR",
63+
UiPathErrorCode.EXECUTION_ERROR,
6364
"Python script execution failed",
6465
f"Error: {str(e)}",
6566
UiPathErrorCategory.SYSTEM,

src/uipath/_cli/_runtime/_script_executor.py

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,7 @@
88

99
from pydantic import BaseModel
1010

11-
from ._contracts import (
12-
UiPathErrorCategory,
13-
UiPathRuntimeError,
14-
)
11+
from ._contracts import UiPathErrorCategory, UiPathErrorCode, UiPathRuntimeError
1512

1613
T = TypeVar("T")
1714

@@ -28,15 +25,15 @@ def validate_entrypoint(self) -> None:
2825
"""Validate runtime inputs."""
2926
if not self.entrypoint:
3027
raise UiPathRuntimeError(
31-
"ENTRYPOINT_MISSING",
28+
UiPathErrorCode.ENTRYPOINT_MISSING,
3229
"No entrypoint specified",
3330
"Please provide a path to a Python script.",
3431
UiPathErrorCategory.USER,
3532
)
3633

3734
if not os.path.exists(self.entrypoint):
3835
raise UiPathRuntimeError(
39-
"ENTRYPOINT_NOT_FOUND",
36+
UiPathErrorCode.ENTRYPOINT_NOT_FOUND,
4037
"Script not found",
4138
f"Script not found at path {self.entrypoint}.",
4239
UiPathErrorCategory.USER,
@@ -47,7 +44,7 @@ async def _execute_python_script(self, input_data: Any) -> Any:
4744
spec = importlib.util.spec_from_file_location("dynamic_module", self.entrypoint)
4845
if not spec or not spec.loader:
4946
raise UiPathRuntimeError(
50-
"IMPORT_ERROR",
47+
UiPathErrorCode.IMPORT_ERROR,
5148
"Module import failed",
5249
f"Could not load spec for {self.entrypoint}",
5350
UiPathErrorCategory.USER,
@@ -58,7 +55,7 @@ async def _execute_python_script(self, input_data: Any) -> Any:
5855
spec.loader.exec_module(module)
5956
except Exception as e:
6057
raise UiPathRuntimeError(
61-
"MODULE_EXECUTION_ERROR",
58+
UiPathErrorCode.MODULE_EXECUTION_ERROR,
6259
"Module execution failed",
6360
f"Error executing module: {str(e)}",
6461
UiPathErrorCategory.USER,
@@ -84,7 +81,7 @@ async def _execute_python_script(self, input_data: Any) -> Any:
8481
)
8582
except Exception as e:
8683
raise UiPathRuntimeError(
87-
"FUNCTION_EXECUTION_ERROR",
84+
UiPathErrorCode.FUNCTION_EXECUTION_ERROR,
8885
f"Error executing {func_name} function",
8986
f"Error: {str(e)}",
9087
UiPathErrorCategory.USER,
@@ -114,7 +111,7 @@ async def _execute_python_script(self, input_data: Any) -> Any:
114111
)
115112
except Exception as e:
116113
raise UiPathRuntimeError(
117-
"FUNCTION_EXECUTION_ERROR",
114+
UiPathErrorCode.FUNCTION_EXECUTION_ERROR,
118115
f"Error executing {func_name} function with typed input",
119116
f"Error: {str(e)}",
120117
UiPathErrorCategory.USER,
@@ -135,14 +132,14 @@ async def _execute_python_script(self, input_data: Any) -> Any:
135132
)
136133
except Exception as e:
137134
raise UiPathRuntimeError(
138-
"FUNCTION_EXECUTION_ERROR",
135+
UiPathErrorCode.FUNCTION_EXECUTION_ERROR,
139136
f"Error executing {func_name} function with dictionary input",
140137
f"Error: {str(e)}",
141138
UiPathErrorCategory.USER,
142139
) from e
143140

144141
raise UiPathRuntimeError(
145-
"ENTRYPOINT_FUNCTION_MISSING",
142+
UiPathErrorCode.ENTRYPOINT_FUNCTION_MISSING,
146143
"No entry function found",
147144
f"No main function (main, run, or execute) found in {self.entrypoint}",
148145
UiPathErrorCategory.USER,

0 commit comments

Comments
 (0)