IBM-Blockchain-Archive / ibm-blockchain-issues

Having issues with the IBM Blockchain Bluemix service? Let us know!
13 stars 12 forks source link

Returning errors from Invoke functions #85

Closed JoseMiguelHerrera closed 7 years ago

JoseMiguelHerrera commented 7 years ago

Hi There,

I've been noticing that there is a difference in the way errors are returned in the chaincode between invoke() and query().

When I return an error like so: return nil, errors.New("generic error")

the error is propagated properly only when the error came from a function called through query().

However, when called through invoke(), there is no apparent way to detect the error. When I try it from the Blockchain API portal, I simply get a 200 OK response... and through the HFC library it simply times out.

Getting error signals back from the chaincode/smart contract is very important, so what is happening?

Cheers, Jose Herrera

mrshah-at-ibm commented 7 years ago

@JoseMiguelHerrera the call to invoke() returns 200 OK immediately with a transaction ID to indicate a successful call to invoke function and does not represent the result of the function. You will have to use eventhub or call block api to see if the transaction was successful.

JoseMiguelHerrera commented 7 years ago

@mrshah-at-ibm thanks for the quick response, I'm glad it's possible to get the response somehow. Could you link me to a documentation or an example where this is done? Thanks!

mrshah-at-ibm commented 7 years ago

Here is an example - https://github.com/IBM-Blockchain/SDK-Demo

JoseMiguelHerrera commented 7 years ago

@mrshah-at-ibm in this demo there isn't a way to get back errors propagated from the chaincode. For example, in the chaincode invoke function you have this line checking for the correct number of args:

if len(args) != 3 {
        return nil, errors.New("Incorrect number of arguments. Expecting 3")
    }

Then I went into config.json to get rid of an invoke argument, reducing them to 2. When run, I get feedback that it has been submitted, and then a timeout error. The argument error is lost somehow.

If there is a way (maybe with the "custom event listening"), the demo isn't doing it.

JoseMiguelHerrera commented 7 years ago

I gave it a try with the event hub custom events but I'm not sure if I use it to simulate getting back errors.

  // Trigger the invoke transaction
  var invokeTx = userObj.invoke(invokeRequest);

  // Print the invoke results
  invokeTx.on('submitted', function (results) {
    // Invoke transaction submitted successfully
    console.log(util.format("\nSuccessfully submitted chaincode invoke transaction: request=%j, response=%j", invokeRequest, results));
  });
  invokeTx.on('complete', function (results) { 
    // Invoke transaction completed successfully
    console.log(util.format("\nSuccessfully completed chaincode invoke transaction: request=%j, response=%j", invokeRequest, results));
    callback(null, results);
  });
  invokeTx.on('error', function (err) { //USELESS, does not actually get errors
    // Invoke transaction submission failed
    console.log(util.format("\nFailed to submit chaincode invoke transaction: request=%j, error=%j", invokeRequest, err));
    callback(err, null);
  });

  //Listen to custom events
  var regid = eh.registerChaincodeEvent(chaincodeID, "unknownFunc", function (event) {
    customErr = new Error();
    customErr.code = 400;
    customErr.message = util.format("unknown function error, payload: %j\n", event.payload.toString());
    console.log(customErr.message);
    eh.unregisterChaincodeEvent(regid);
  });

Is there a design pattern that can simply tell me right away which error an invoke threw?

mrshah-at-ibm commented 7 years ago

I haven't used it much, thus I am not sure if it can give back the exact error.

dshuffma-ibm commented 7 years ago

closing due to inactivity