diff --git a/api/core/helper/code_executor/javascript/javascript_transformer.py b/api/core/helper/code_executor/javascript/javascript_transformer.py index 439608bebd..62489cdf29 100644 --- a/api/core/helper/code_executor/javascript/javascript_transformer.py +++ b/api/core/helper/code_executor/javascript/javascript_transformer.py @@ -11,57 +11,16 @@ class NodeJsTemplateTransformer(TemplateTransformer): // declare main function {cls._code_placeholder} - try {{ - // decode and prepare input object - var inputs_obj = JSON.parse(Buffer.from('{cls._inputs_placeholder}', 'base64').toString('utf-8')) + // decode and prepare input object + var inputs_obj = JSON.parse(Buffer.from('{cls._inputs_placeholder}', 'base64').toString('utf-8')) - // Preprocess inputs to handle number precision issues - function preprocessInputs(obj) {{ - if (typeof obj === 'object' && obj !== null) {{ - for (var key in obj) {{ - if (obj.hasOwnProperty(key)) {{ - if (typeof obj[key] === 'string') {{ - // Try to parse string as number if it looks like a number - var num = parseFloat(obj[key]); - if (!isNaN(num) && obj[key].trim() === num.toString()) {{ - obj[key] = num; - }} - }} else if (typeof obj[key] === 'object') {{ - preprocessInputs(obj[key]); - }} - }} - }} - }} - return obj; - }} - - // Preprocess inputs - inputs_obj = preprocessInputs(inputs_obj); + // execute main function + var output_obj = main(inputs_obj) - // execute main function - var output_obj = main(inputs_obj) - - // Handle precision numbers properly in JSON.stringify - var output_json = JSON.stringify(output_obj, function(key, value) {{ - // Ensure numbers are properly serialized - if (typeof value === 'number') {{ - // Handle very small numbers that might cause precision issues - if (Math.abs(value) < 1e-1 && Math.abs(value) > 0) {{ - // Convert to string to preserve precision - return value.toString(); - }} - }} - return value; - }}) - - var result = `<>${{output_json}}<>` - console.log(result) - }} catch (error) {{ - console.error('JavaScript execution error:', error.message) - // Provide more detailed error information - var errorResult = `<>{{"error": "JavaScript execution failed: " + error.message}}<>` - console.log(errorResult) - }} + // convert output to json and print + var output_json = JSON.stringify(output_obj) + var result = `<>${{output_json}}<>` + console.log(result) """ ) - return runner_script \ No newline at end of file + return runner_script diff --git a/api/core/helper/code_executor/template_transformer.py b/api/core/helper/code_executor/template_transformer.py index f6e9c8a3e8..84f212a9c1 100644 --- a/api/core/helper/code_executor/template_transformer.py +++ b/api/core/helper/code_executor/template_transformer.py @@ -38,6 +38,7 @@ class TemplateTransformer(ABC): :param response: response :return: """ + try: result_str = cls.extract_result_str_from_response(response) result = json.loads(result_str) @@ -48,17 +49,42 @@ class TemplateTransformer(ABC): raise e except Exception as e: raise ValueError(f"Unexpected error during response transformation: {str(e)}") - + # Check if the result contains an error if isinstance(result, dict) and "error" in result: raise ValueError(f"JavaScript execution error: {result['error']}") - + if not isinstance(result, dict): raise ValueError(f"Result must be a dict, got {type(result).__name__}") if not all(isinstance(k, str) for k in result): raise ValueError("Result keys must be strings") + + # Post-process the result to convert scientific notation strings back to numbers + result = cls._post_process_result(result) return result + @classmethod + def _post_process_result(cls, result: dict[Any, Any]) -> dict[Any, Any]: + """ + Post-process the result to convert scientific notation strings back to numbers + """ + + def convert_scientific_notation(value): + if isinstance(value, str): + # Check if the string looks like scientific notation + if re.match(r"^-?\d+\.?\d*e[+-]\d+$", value, re.IGNORECASE): + try: + return float(value) + except ValueError: + pass + elif isinstance(value, dict): + return {k: convert_scientific_notation(v) for k, v in value.items()} + elif isinstance(value, list): + return [convert_scientific_notation(v) for v in value] + return value + + return convert_scientific_notation(result) # type: ignore[no-any-return] + @classmethod @abstractmethod def get_runner_script(cls) -> str: