Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 29 additions & 14 deletions src/uipath_langchain/agent/tools/process_tool.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,21 +26,36 @@

from .utils import sanitize_tool_name

_START_JOBS_ERRORS: dict[tuple[int, str | None], tuple[str, UiPathErrorCategory]] = {
(404, "1002"): (
"Could not find process for tool '{tool}'. Please check if the process is deployed in the configured folder.",
UiPathErrorCategory.DEPLOYMENT,
),
(400, "1100"): (
"Could not find folder for tool '{tool}'. Please check if the folder exists and is accessible by the robot.",
UiPathErrorCategory.DEPLOYMENT,
),
(409, None): (
"Cannot start process for tool '{tool}': {message}",
UiPathErrorCategory.DEPLOYMENT,
),
_START_JOBS_404_TEMPLATES: dict[str, str] = {
"AssociatedProcessNotFound": "Could not find process for tool '{tool}'. Please check if the process is deployed in the configured folder.",
"AttachmentNotFound": "Could not find an attachment passed to tool '{tool}'. Please check that the attachments provided to the tool still exist.",
}

_START_JOBS_404_FALLBACK_TEMPLATE = "Could not start process for tool '{tool}': an item required to start the job was not found. Server message: {message}"


def _start_jobs_errors(
e: EnrichedException,
) -> dict[tuple[int, str | None], tuple[str, UiPathErrorCategory]]:
server_message = (e.error_info.message if e.error_info else None) or ""
not_found_template = _START_JOBS_404_TEMPLATES.get(
server_message, _START_JOBS_404_FALLBACK_TEMPLATE
)
return {
(404, "1002"): (
not_found_template,
UiPathErrorCategory.DEPLOYMENT,
),
(400, "1100"): (
"Could not find folder for tool '{tool}'. Please check if the folder exists and is accessible by the robot.",
UiPathErrorCategory.DEPLOYMENT,
),
(409, None): (
"Cannot start process for tool '{tool}': {message}",
UiPathErrorCategory.DEPLOYMENT,
),
}


def create_process_tool(
resource: AgentProcessToolResourceConfig,
Expand Down Expand Up @@ -91,7 +106,7 @@ async def start_job():
except EnrichedException as e:
raise_for_enriched(
e,
_START_JOBS_ERRORS,
_start_jobs_errors(e),
title=f"Failed to execute tool '{resource.name}'",
tool=resource.name,
)
Expand Down
60 changes: 60 additions & 0 deletions tests/agent/test_exception_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

from uipath_langchain.agent.exceptions import AgentRuntimeError, AgentRuntimeErrorCode
from uipath_langchain.agent.exceptions.helpers import raise_for_enriched
from uipath_langchain.agent.tools.process_tool import _start_jobs_errors


def _make_enriched(
Expand Down Expand Up @@ -138,3 +139,62 @@
with pytest.raises(AgentRuntimeError) as exc_info:
raise_for_enriched(err, _KNOWN_ERRORS, title=_TITLE, tool="T")
assert exc_info.value.__cause__ is err


class TestStartJobsNotFound:
def test_process_not_found(self) -> None:
err = _make_enriched(
404,
{"errorCode": "1002", "message": "AssociatedProcessNotFound"},
)
with pytest.raises(AgentRuntimeError) as exc_info:

Check warning on line 150 in tests/agent/test_exception_helpers.py

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Refactor this exception test to have only one invocation possibly throwing an exception.

See more on https://sonarcloud.io/project/issues?id=UiPath_uipath-langchain-python&issues=AaBdA_Q3pmFCwR3HkRxw&open=AaBdA_Q3pmFCwR3HkRxw&pullRequest=1060
raise_for_enriched(
err, _start_jobs_errors(err), title=_TITLE, tool="MyProcess"
)
assert exc_info.value.error_info.detail == (
"Could not find process for tool 'MyProcess'. "
"Please check if the process is deployed in the configured folder."
)

def test_attachment_not_found(self) -> None:
err = _make_enriched(
404,
{"errorCode": "1002", "message": "AttachmentNotFound"},
)
with pytest.raises(AgentRuntimeError) as exc_info:

Check warning on line 164 in tests/agent/test_exception_helpers.py

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Refactor this exception test to have only one invocation possibly throwing an exception.

See more on https://sonarcloud.io/project/issues?id=UiPath_uipath-langchain-python&issues=AaBdA_Q3pmFCwR3HkRxx&open=AaBdA_Q3pmFCwR3HkRxx&pullRequest=1060
raise_for_enriched(
err, _start_jobs_errors(err), title=_TITLE, tool="MyProcess"
)
detail = exc_info.value.error_info.detail
assert "Could not find process" not in detail
assert detail == (
"Could not find an attachment passed to tool 'MyProcess'. "
"Please check that the attachments provided to the tool still exist."
)

def test_unknown_message_includes_server_message(self) -> None:
err = _make_enriched(
404,
{"errorCode": "1002", "message": "SomeOtherItemNotFound"},
)
with pytest.raises(AgentRuntimeError) as exc_info:

Check warning on line 180 in tests/agent/test_exception_helpers.py

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Refactor this exception test to have only one invocation possibly throwing an exception.

See more on https://sonarcloud.io/project/issues?id=UiPath_uipath-langchain-python&issues=AaBdA_Q3pmFCwR3HkRxy&open=AaBdA_Q3pmFCwR3HkRxy&pullRequest=1060
raise_for_enriched(
err, _start_jobs_errors(err), title=_TITLE, tool="MyProcess"
)
assert exc_info.value.error_info.detail == (
"Could not start process for tool 'MyProcess': an item required "
"to start the job was not found. "
"Server message: SomeOtherItemNotFound"
)

def test_empty_server_message(self) -> None:
err = _make_enriched(404, {"errorCode": "1002"})
with pytest.raises(AgentRuntimeError) as exc_info:

Check warning on line 192 in tests/agent/test_exception_helpers.py

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Refactor this exception test to have only one invocation possibly throwing an exception.

See more on https://sonarcloud.io/project/issues?id=UiPath_uipath-langchain-python&issues=AaBdA_Q3pmFCwR3HkRxz&open=AaBdA_Q3pmFCwR3HkRxz&pullRequest=1060
raise_for_enriched(
err, _start_jobs_errors(err), title=_TITLE, tool="MyProcess"
)
assert exc_info.value.error_info.detail == (
"Could not start process for tool 'MyProcess': an item required "
"to start the job was not found. "
"Server message: "
)
10 changes: 5 additions & 5 deletions uv.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading