Suppose the user has authored the following Node.js function. You want to execute it in webtasks while capturing the output generated by console.log
calls within that function:
function (param, callback) {
console.log('In my custom function. Parameter is:', param);
callback(null, { hello: 'world' });
}
The code you need to send for execution to webtasks must wrap this user supplied code in the following way:
var util = require('util');
module.exports = function (ctx, cb) {
// Intercept implementation of `console.log` so that it is within the scope
// of the user function invocation below.
var console = {
log: function () {
console._stdout.push(util.format.apply(global, arguments));
global.console.log.apply(global, arguments);
},
_stdout: []
};
for (var i in global.console)
if (!console[i])
console[i] = global.console[i];
// Initialize param to whatever input you need to pass to the custom
// function, possibly based on the value of `ctx`.
var param = {};
// Call the user supplied function. The newly created console will be
// in its scope. In addition, intercept the callback to post-process
// results and capture logs.
(
// This is the code of user supplied function, embedded verbatim
function (param, callback) {
console.log('In my custom function. Parameter is:', param);
callback(null, { hello: 'world' });
}
)(param, function (error, data) {
var ret = {
stdout: console._stdout
};
if (error) {
ret.error = error.message || error.toString();
}
else {
ret.data = data;
}
cb(null, ret);
});
}
Given this wrapper above, every time the custom function completes by calling its callback (regardless if with error or a response value), the webtaks code will return a JSON object formatted as follows:
// In case of a successful completion:
{
stdout: [], // array of strings representing `console.log` calls
data: ... // whatever JSON-serializable entity custom code passed
// as the second parameter to the callback
}
// In case of completion with an error (error passed to callback function):
{
stdout: [], // array of strings representing `console.log` calls
error: 'some string' // the error
}
The wrapper preamble that formats input parameters to the custom function as well as the callback wrapper may of course be fine-tuned to pass in and respond with a different result, but this snippet hopefully illustares the core idea.