| 
					
				 | 
			
			
				@@ -12,6 +12,12 @@ from core.workflow.nodes.code.entities import CodeNodeData 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 from core.workflow.nodes.enums import NodeType 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 from models.workflow import WorkflowNodeExecutionStatus 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+from .exc import ( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    CodeNodeError, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    DepthLimitError, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    OutputValidationError, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 class CodeNode(BaseNode[CodeNodeData]): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     _node_data_cls = CodeNodeData 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -60,7 +66,7 @@ class CodeNode(BaseNode[CodeNodeData]): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             # Transform result 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             result = self._transform_result(result, self.node_data.outputs) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        except (CodeExecutionError, ValueError) as e: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        except (CodeExecutionError, CodeNodeError) as e: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             return NodeRunResult(status=WorkflowNodeExecutionStatus.FAILED, inputs=variables, error=str(e)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         return NodeRunResult(status=WorkflowNodeExecutionStatus.SUCCEEDED, inputs=variables, outputs=result) 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -76,10 +82,10 @@ class CodeNode(BaseNode[CodeNodeData]): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             if value is None: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 return None 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             else: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                raise ValueError(f"Output variable `{variable}` must be a string") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                raise OutputValidationError(f"Output variable `{variable}` must be a string") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         if len(value) > dify_config.CODE_MAX_STRING_LENGTH: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            raise ValueError( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            raise OutputValidationError( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 f"The length of output variable `{variable}` must be" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 f" less than {dify_config.CODE_MAX_STRING_LENGTH} characters" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             ) 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -97,10 +103,10 @@ class CodeNode(BaseNode[CodeNodeData]): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             if value is None: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 return None 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             else: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                raise ValueError(f"Output variable `{variable}` must be a number") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                raise OutputValidationError(f"Output variable `{variable}` must be a number") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         if value > dify_config.CODE_MAX_NUMBER or value < dify_config.CODE_MIN_NUMBER: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            raise ValueError( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            raise OutputValidationError( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 f"Output variable `{variable}` is out of range," 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 f" it must be between {dify_config.CODE_MIN_NUMBER} and {dify_config.CODE_MAX_NUMBER}." 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             ) 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -108,7 +114,7 @@ class CodeNode(BaseNode[CodeNodeData]): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         if isinstance(value, float): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             # raise error if precision is too high 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             if len(str(value).split(".")[1]) > dify_config.CODE_MAX_PRECISION: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                raise ValueError( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                raise OutputValidationError( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                     f"Output variable `{variable}` has too high precision," 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                     f" it must be less than {dify_config.CODE_MAX_PRECISION} digits." 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 ) 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -125,7 +131,7 @@ class CodeNode(BaseNode[CodeNodeData]): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         :return: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         """ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         if depth > dify_config.CODE_MAX_DEPTH: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            raise ValueError(f"Depth limit ${dify_config.CODE_MAX_DEPTH} reached, object too deep.") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            raise DepthLimitError(f"Depth limit ${dify_config.CODE_MAX_DEPTH} reached, object too deep.") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         transformed_result = {} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         if output_schema is None: 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -177,14 +183,14 @@ class CodeNode(BaseNode[CodeNodeData]): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                                         depth=depth + 1, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                                     ) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                         else: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                            raise ValueError( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                            raise OutputValidationError( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                                 f"Output {prefix}.{output_name} is not a valid array." 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                                 f" make sure all elements are of the same type." 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                             ) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 elif output_value is None: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                     pass 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 else: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    raise ValueError(f"Output {prefix}.{output_name} is not a valid type.") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    raise OutputValidationError(f"Output {prefix}.{output_name} is not a valid type.") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             return result 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -192,7 +198,7 @@ class CodeNode(BaseNode[CodeNodeData]): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         for output_name, output_config in output_schema.items(): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             dot = "." if prefix else "" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             if output_name not in result: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                raise ValueError(f"Output {prefix}{dot}{output_name} is missing.") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                raise OutputValidationError(f"Output {prefix}{dot}{output_name} is missing.") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             if output_config.type == "object": 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 # check if output is object 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -200,7 +206,7 @@ class CodeNode(BaseNode[CodeNodeData]): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                     if isinstance(result.get(output_name), type(None)): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                         transformed_result[output_name] = None 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                     else: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        raise ValueError( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        raise OutputValidationError( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                             f"Output {prefix}{dot}{output_name} is not an object," 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                             f" got {type(result.get(output_name))} instead." 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                         ) 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -228,13 +234,13 @@ class CodeNode(BaseNode[CodeNodeData]): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                     if isinstance(result[output_name], type(None)): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                         transformed_result[output_name] = None 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                     else: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        raise ValueError( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        raise OutputValidationError( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                             f"Output {prefix}{dot}{output_name} is not an array," 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                             f" got {type(result.get(output_name))} instead." 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                         ) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 else: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                     if len(result[output_name]) > dify_config.CODE_MAX_NUMBER_ARRAY_LENGTH: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        raise ValueError( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        raise OutputValidationError( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                             f"The length of output variable `{prefix}{dot}{output_name}` must be" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                             f" less than {dify_config.CODE_MAX_NUMBER_ARRAY_LENGTH} elements." 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                         ) 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -249,13 +255,13 @@ class CodeNode(BaseNode[CodeNodeData]): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                     if isinstance(result[output_name], type(None)): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                         transformed_result[output_name] = None 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                     else: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        raise ValueError( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        raise OutputValidationError( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                             f"Output {prefix}{dot}{output_name} is not an array," 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                             f" got {type(result.get(output_name))} instead." 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                         ) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 else: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                     if len(result[output_name]) > dify_config.CODE_MAX_STRING_ARRAY_LENGTH: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        raise ValueError( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        raise OutputValidationError( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                             f"The length of output variable `{prefix}{dot}{output_name}` must be" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                             f" less than {dify_config.CODE_MAX_STRING_ARRAY_LENGTH} elements." 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                         ) 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -270,13 +276,13 @@ class CodeNode(BaseNode[CodeNodeData]): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                     if isinstance(result[output_name], type(None)): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                         transformed_result[output_name] = None 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                     else: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        raise ValueError( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        raise OutputValidationError( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                             f"Output {prefix}{dot}{output_name} is not an array," 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                             f" got {type(result.get(output_name))} instead." 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                         ) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 else: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                     if len(result[output_name]) > dify_config.CODE_MAX_OBJECT_ARRAY_LENGTH: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        raise ValueError( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        raise OutputValidationError( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                             f"The length of output variable `{prefix}{dot}{output_name}` must be" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                             f" less than {dify_config.CODE_MAX_OBJECT_ARRAY_LENGTH} elements." 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                         ) 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -286,7 +292,7 @@ class CodeNode(BaseNode[CodeNodeData]): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                             if value is None: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                                 pass 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                             else: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                                raise ValueError( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                raise OutputValidationError( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                                     f"Output {prefix}{dot}{output_name}[{i}] is not an object," 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                                     f" got {type(value)} instead at index {i}." 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                                 ) 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -303,13 +309,13 @@ class CodeNode(BaseNode[CodeNodeData]): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                         for i, value in enumerate(result[output_name]) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                     ] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             else: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                raise ValueError(f"Output type {output_config.type} is not supported.") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                raise OutputValidationError(f"Output type {output_config.type} is not supported.") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             parameters_validated[output_name] = True 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         # check if all output parameters are validated 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         if len(parameters_validated) != len(result): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            raise ValueError("Not all output parameters are validated.") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            raise CodeNodeError("Not all output parameters are validated.") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         return transformed_result 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 |