Skip to content

Commit

Permalink
improved error handling
Browse files Browse the repository at this point in the history
  • Loading branch information
poing committed Jan 18, 2024
1 parent f61a47c commit 06a52b9
Show file tree
Hide file tree
Showing 2 changed files with 188 additions and 0 deletions.
97 changes: 97 additions & 0 deletions gems/wrapperV3.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
// wrapperV3.js

/*
This is the third working version of the wrapper. Better error handling and accepting multiple JavaScript command for the secrets.js package.
*/

// Require the secrets package and assign it to a variable
const secrets = require('../secrets.js/secrets.js');

// If the script is executed directly, call the appropriate function based on arguments
if (require.main === module) {
const inputJson = process.argv[2];

if (!inputJson) {
console.error("No input provided.");
process.exit(1);
}

try {
const inputData = JSON.parse(inputJson);
const output = { results: [] };

// Check if inputData has a "tasks" key
if ("tasks" in inputData && Array.isArray(inputData.tasks)) {
// Loop through tasks
for (const task of inputData.tasks) {
const taskResult = {};

// Check if task has a "setup" key
if ("setup" in task && Array.isArray(task.setup)) {
// Loop through setup tasks
for (const setupTask of task.setup) {
const setupFunction = setupTask.function;
const setupArguments = setupTask.args;

// Dynamically call the setup function
const setupFn = secrets[setupFunction];

if (setupFn && typeof setupFn === 'function') {
try {
// Call the setup function
setupFn(...setupArguments);
taskResult.setupResult = { success: true };
} catch (error) {
// Capture and report the error to stderr
console.error(error.message);
taskResult.setupResult = { success: false, error: error.message };
}
} else {
// Report unknown function
const errorMessage = `Unknown function: ${setupFunction}`;
console.error(errorMessage);
taskResult.setupResult = { success: false, error: errorMessage };
}
}
}

// Check if task has a "start" key
if ("start" in task) {
const functionName = task.start.function;
const arguments = task.start.args;

// Dynamically call the main function
const selectedFunction = secrets[functionName];

if (selectedFunction && typeof selectedFunction === 'function') {
try {
// Call the main function
const result = selectedFunction(...arguments);
taskResult.startResult = { success: true, result };
} catch (error) {
// Capture and report the error to stderr
console.error(error.message);
taskResult.startResult = { success: false, error: error.message };
}
} else {
// Report unknown function
const errorMessage = `Unknown function: ${functionName}`;
console.error(errorMessage);
taskResult.startResult = { success: false, error: errorMessage };
}
}

// Add task result to the output
output.results.push(taskResult);
}

// Print the output as a JSON object
console.log(JSON.stringify(output));
}
} catch (error) {
console.error("Error parsing or executing:", error.message);
// In case of an error, print a JSON object with an "error" key
console.log(JSON.stringify({ error: error.message }));
}
}

91 changes: 91 additions & 0 deletions gems/wrapperV3_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
#! /usr/bin/env python3
# -*- coding: utf-8 -*-
# vim: set et sw=4 fenc=utf-8:
#
# wrapperV3_test.py

"""
This script demonstrates the third working version of calling Node.js to execute JavaScript using a wrapper to load the secrets.js package.
This version handles multiple commands, sent as setup and start. And have improved error handling.
"""

import json
import subprocess

# Path to the Node.js wrapper script
JS_FILE_PATH = "wrapperV3.js"

def run_js_functions(input_data):
"""
Run a JavaScript function using the Node.js wrapper.
Args:
input_data (dict): Dictionary containing the function name and arguments.
Returns:
The result of the JavaScript function or None if there is an error.
"""

# Enclose input_json in single quotes
js_command = ["node", JS_FILE_PATH, input_data]

try:
# Run the command and capture the output and stderr
result = subprocess.run(js_command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True, check=True)

# Debugging statement to print stdout and stderr
# print("stdout:", result.stdout)
# print("stderr:", result.stderr)

try:
# Attempt to load the entire stdout as JSON
js_result = json.loads(result.stdout)

# Check if the result has 'error' or 'results' key
if js_result is not None and "results" in js_result:
start_result = js_result.get("results", [])[0].get("startResult", {}).get("result")
if start_result is not None:
print("Result of 'start' function:", start_result)
else:
print("No result found for 'start' function.")
elif js_result is not None and "error" in js_result:
print("JavaScript error:", js_result.get("error"))
else:
print("JavaScript output is missing 'error' or 'results' key.")

# Print stderr if it exists
if result.stderr:
print("JavaScript stderr:", result.stderr)

except json.JSONDecodeError as e:
print("Error decoding JSON:", e)
print("Raw stdout content:", result.stdout)

except subprocess.CalledProcessError as e:
# Print the error from the JavaScript script
js_error = result.stderr.strip()
print("JavaScript error:", js_error)
return None


# Example usage
# Setup commands
setup = [
{'function': 'setRNG', 'args': ['testRandom']},
]

# Dynamic Values
foo = ['1234abc', 6, 3]

# Main function
main = {'function': 'share', 'args': foo}

# Combine setup and main
tasks = {'tasks': [{'setup': setup, 'start': main}]}

# Convert the Python dictionary to JSON
json_data = json.dumps(tasks, indent=None)
#print(json_data)

run_js_functions(json_data)

0 comments on commit 06a52b9

Please sign in to comment.