Przeglądaj źródła

refactor(http_request): add custom exception handling for HTTP request nodes (#10219)

-LAN- 5 miesięcy temu
rodzic
commit
2adab7f71a

+ 18 - 0
api/core/workflow/nodes/http_request/exc.py

@@ -0,0 +1,18 @@
+class HttpRequestNodeError(ValueError):
+    """Custom error for HTTP request node."""
+
+
+class AuthorizationConfigError(HttpRequestNodeError):
+    """Raised when authorization config is missing or invalid."""
+
+
+class FileFetchError(HttpRequestNodeError):
+    """Raised when a file cannot be fetched."""
+
+
+class InvalidHttpMethodError(HttpRequestNodeError):
+    """Raised when an invalid HTTP method is used."""
+
+
+class ResponseSizeError(HttpRequestNodeError):
+    """Raised when the response size exceeds the allowed threshold."""

+ 13 - 7
api/core/workflow/nodes/http_request/executor.py

@@ -18,6 +18,12 @@ from .entities import (
     HttpRequestNodeTimeout,
     Response,
 )
+from .exc import (
+    AuthorizationConfigError,
+    FileFetchError,
+    InvalidHttpMethodError,
+    ResponseSizeError,
+)
 
 BODY_TYPE_TO_CONTENT_TYPE = {
     "json": "application/json",
@@ -51,7 +57,7 @@ class Executor:
         # If authorization API key is present, convert the API key using the variable pool
         if node_data.authorization.type == "api-key":
             if node_data.authorization.config is None:
-                raise ValueError("authorization config is required")
+                raise AuthorizationConfigError("authorization config is required")
             node_data.authorization.config.api_key = variable_pool.convert_template(
                 node_data.authorization.config.api_key
             ).text
@@ -116,7 +122,7 @@ class Executor:
                     file_selector = data[0].file
                     file_variable = self.variable_pool.get_file(file_selector)
                     if file_variable is None:
-                        raise ValueError(f"cannot fetch file with selector {file_selector}")
+                        raise FileFetchError(f"cannot fetch file with selector {file_selector}")
                     file = file_variable.value
                     self.content = file_manager.download(file)
                 case "x-www-form-urlencoded":
@@ -155,12 +161,12 @@ class Executor:
         headers = deepcopy(self.headers) or {}
         if self.auth.type == "api-key":
             if self.auth.config is None:
-                raise ValueError("self.authorization config is required")
+                raise AuthorizationConfigError("self.authorization config is required")
             if authorization.config is None:
-                raise ValueError("authorization config is required")
+                raise AuthorizationConfigError("authorization config is required")
 
             if self.auth.config.api_key is None:
-                raise ValueError("api_key is required")
+                raise AuthorizationConfigError("api_key is required")
 
             if not authorization.config.header:
                 authorization.config.header = "Authorization"
@@ -183,7 +189,7 @@ class Executor:
             else dify_config.HTTP_REQUEST_NODE_MAX_TEXT_SIZE
         )
         if executor_response.size > threshold_size:
-            raise ValueError(
+            raise ResponseSizeError(
                 f'{"File" if executor_response.is_file else "Text"} size is too large,'
                 f' max size is {threshold_size / 1024 / 1024:.2f} MB,'
                 f' but current size is {executor_response.readable_size}.'
@@ -196,7 +202,7 @@ class Executor:
         do http request depending on api bundle
         """
         if self.method not in {"get", "head", "post", "put", "delete", "patch"}:
-            raise ValueError(f"Invalid http method {self.method}")
+            raise InvalidHttpMethodError(f"Invalid http method {self.method}")
 
         request_args = {
             "url": self.url,

+ 2 - 1
api/core/workflow/nodes/http_request/node.py

@@ -20,6 +20,7 @@ from .entities import (
     HttpRequestNodeTimeout,
     Response,
 )
+from .exc import HttpRequestNodeError
 
 HTTP_REQUEST_DEFAULT_TIMEOUT = HttpRequestNodeTimeout(
     connect=dify_config.HTTP_REQUEST_MAX_CONNECT_TIMEOUT,
@@ -77,7 +78,7 @@ class HttpRequestNode(BaseNode[HttpRequestNodeData]):
                     "request": http_executor.to_log(),
                 },
             )
-        except Exception as e:
+        except HttpRequestNodeError as e:
             logger.warning(f"http request node {self.node_id} failed to run: {e}")
             return NodeRunResult(
                 status=WorkflowNodeExecutionStatus.FAILED,