diff --git a/api/core/workflow/nodes/http_request/exc.py b/api/core/workflow/nodes/http_request/exc.py new file mode 100644 index 0000000000..7a5ab7dbc1 --- /dev/null +++ b/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.""" diff --git a/api/core/workflow/nodes/http_request/executor.py b/api/core/workflow/nodes/http_request/executor.py index 6872478299..6204fc2644 100644 --- a/api/core/workflow/nodes/http_request/executor.py +++ b/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, diff --git a/api/core/workflow/nodes/http_request/node.py b/api/core/workflow/nodes/http_request/node.py index a037bee665..61c661e587 100644 --- a/api/core/workflow/nodes/http_request/node.py +++ b/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,