What does ctx.stub.getState(KEY) return when no state exists for 'KEY'?

Viewed 601

In the Commercial Paper example of Hyperledger Fabric, there is a StateListImpl class that implement getState like this:

    @Override
    public State getState(String key) {

        CompositeKey ledgerKey = this.ctx.getStub().createCompositeKey(this.name, State.splitKey(key));

        byte[] data = this.ctx.getStub().getState(ledgerKey.toString());
        if (data != null) {
            State state = this.deserializer.deserialize(data);
            return state;
        } else {
            return null;
        }
    }

But, when I call this StateListImpl.getState function with a Key that doesn't exists, the condition data != null its true (and an exception is ocurring inside deserializer), so it seems that ctx.stub.getState(ledgerKey) is not returning null. I've searched in fabric documentation (and in its javadocs) and doesn't say anything about what happens when key isn't in the ledger.

Well, what returns ctx.stub.getState(KEY) if KEY state is not in the ledger?

2 Answers

In Java is not enough checking for null, you have to check also for the length of the byte array, I'm using the following code:

final String data = stub.getStringState(id);
if (StringUtils.isEmpty(data)) {
    throw new RuntimeException(
      String.format("The item %s doesn't exist", id)
    );
 }

If we look closer at StringUtils.isEmpty it checks for the length

public static boolean isEmpty(CharSequence cs) {
    return cs == null || cs.length() == 0;
}

It is because the getState does not return a null value. Instead, it returns an object that is 'undefined'. So if you change your code to getState(key)===undefined then it should work fine.

Related