Skip to content

Commit 2adab7f

Browse files
authored
refactor(http_request): add custom exception handling for HTTP request nodes (#10219)
1 parent be96f6e commit 2adab7f

File tree

3 files changed

+33
-8
lines changed

3 files changed

+33
-8
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
class HttpRequestNodeError(ValueError):
2+
"""Custom error for HTTP request node."""
3+
4+
5+
class AuthorizationConfigError(HttpRequestNodeError):
6+
"""Raised when authorization config is missing or invalid."""
7+
8+
9+
class FileFetchError(HttpRequestNodeError):
10+
"""Raised when a file cannot be fetched."""
11+
12+
13+
class InvalidHttpMethodError(HttpRequestNodeError):
14+
"""Raised when an invalid HTTP method is used."""
15+
16+
17+
class ResponseSizeError(HttpRequestNodeError):
18+
"""Raised when the response size exceeds the allowed threshold."""

api/core/workflow/nodes/http_request/executor.py

+13-7
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,12 @@
1818
HttpRequestNodeTimeout,
1919
Response,
2020
)
21+
from .exc import (
22+
AuthorizationConfigError,
23+
FileFetchError,
24+
InvalidHttpMethodError,
25+
ResponseSizeError,
26+
)
2127

2228
BODY_TYPE_TO_CONTENT_TYPE = {
2329
"json": "application/json",
@@ -51,7 +57,7 @@ def __init__(
5157
# If authorization API key is present, convert the API key using the variable pool
5258
if node_data.authorization.type == "api-key":
5359
if node_data.authorization.config is None:
54-
raise ValueError("authorization config is required")
60+
raise AuthorizationConfigError("authorization config is required")
5561
node_data.authorization.config.api_key = variable_pool.convert_template(
5662
node_data.authorization.config.api_key
5763
).text
@@ -116,7 +122,7 @@ def _init_body(self):
116122
file_selector = data[0].file
117123
file_variable = self.variable_pool.get_file(file_selector)
118124
if file_variable is None:
119-
raise ValueError(f"cannot fetch file with selector {file_selector}")
125+
raise FileFetchError(f"cannot fetch file with selector {file_selector}")
120126
file = file_variable.value
121127
self.content = file_manager.download(file)
122128
case "x-www-form-urlencoded":
@@ -155,12 +161,12 @@ def _assembling_headers(self) -> dict[str, Any]:
155161
headers = deepcopy(self.headers) or {}
156162
if self.auth.type == "api-key":
157163
if self.auth.config is None:
158-
raise ValueError("self.authorization config is required")
164+
raise AuthorizationConfigError("self.authorization config is required")
159165
if authorization.config is None:
160-
raise ValueError("authorization config is required")
166+
raise AuthorizationConfigError("authorization config is required")
161167

162168
if self.auth.config.api_key is None:
163-
raise ValueError("api_key is required")
169+
raise AuthorizationConfigError("api_key is required")
164170

165171
if not authorization.config.header:
166172
authorization.config.header = "Authorization"
@@ -183,7 +189,7 @@ def _validate_and_parse_response(self, response: httpx.Response) -> Response:
183189
else dify_config.HTTP_REQUEST_NODE_MAX_TEXT_SIZE
184190
)
185191
if executor_response.size > threshold_size:
186-
raise ValueError(
192+
raise ResponseSizeError(
187193
f'{"File" if executor_response.is_file else "Text"} size is too large,'
188194
f' max size is {threshold_size / 1024 / 1024:.2f} MB,'
189195
f' but current size is {executor_response.readable_size}.'
@@ -196,7 +202,7 @@ def _do_http_request(self, headers: dict[str, Any]) -> httpx.Response:
196202
do http request depending on api bundle
197203
"""
198204
if self.method not in {"get", "head", "post", "put", "delete", "patch"}:
199-
raise ValueError(f"Invalid http method {self.method}")
205+
raise InvalidHttpMethodError(f"Invalid http method {self.method}")
200206

201207
request_args = {
202208
"url": self.url,

api/core/workflow/nodes/http_request/node.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
HttpRequestNodeTimeout,
2121
Response,
2222
)
23+
from .exc import HttpRequestNodeError
2324

2425
HTTP_REQUEST_DEFAULT_TIMEOUT = HttpRequestNodeTimeout(
2526
connect=dify_config.HTTP_REQUEST_MAX_CONNECT_TIMEOUT,
@@ -77,7 +78,7 @@ def _run(self) -> NodeRunResult:
7778
"request": http_executor.to_log(),
7879
},
7980
)
80-
except Exception as e:
81+
except HttpRequestNodeError as e:
8182
logger.warning(f"http request node {self.node_id} failed to run: {e}")
8283
return NodeRunResult(
8384
status=WorkflowNodeExecutionStatus.FAILED,

0 commit comments

Comments
 (0)