apache / openwhisk

Apache OpenWhisk is an open source serverless cloud platform
https://openwhisk.apache.org/
Apache License 2.0
6.5k stars 1.16k forks source link

Allow array as JSON result (The action did not produce a valid JSON response: []) #2027

Closed aslom closed 7 years ago

aslom commented 7 years ago

Environment details:

Steps to reproduce the issue:

  1. Run action
function main(params) {
    return [];
}

Provide the expected results and outputs:

[]

Provide the actual results and outputs:

{
  "error": "The action did not produce a valid JSON response: []"
}

Additional information you deem important:

function main(params) {
    return {};
}
aslom commented 7 years ago

I ended up with this workaround but it is kind of ugly to put it into every action that is returning JSON from REST API call ...

    if(json.constructor.name === 'Object') {
      resolve(json);
    } else { // openwhisk fails if response is not JSON object {}
      resolve({ 'result' : json});
    }
rabbah commented 7 years ago

Actions by definition must return an JSON object - it is incorrect to return anything else. Your action may appear to return a JSON array (or any legal JSON value) if you use a web action, e.g., to return { body: []} instead.

I don't see us relaxing this restriction otherwise - it's fundamentally part of the action definition (dictionary in, dictionary out) and permits action composition.

aslom commented 7 years ago

OK - it just makes for ugly code to check and convert output from REST API calls inside action (and I already need to check if output is JSON in first place ...)

Example:

function main(parameters) {
 return new Promise(function(resolve, reject) {
var request = require("request");

var options = { method: 'GET',
  url: 'http://api.wunderground.com/api/%7Bkey%7D/conditions/q/%7Bstate%7D/%7Bplace%7D' };

request(options, function (error, response, body) {
  if (error) {
    reject(error);
  } else {  
    var json = {};
    try {
      json = JSON.parse(body);
    } catch (e) {
      var len = Math.min(body.length, 10);
      var bodyStr = body.substring(0, len);
      json = { 'msg': bodyStr };
      console.log('body=' + bodyStr);
    }
    if(json.constructor.name === 'Object') {
      resolve(json);
    } else { // openwhisk fails if response in not JSON object {}
      resolve({ 'result' : json});
    }
 }
});

 })
}