3

I'm using the python sdk to develop a custom transaction processor por hyperledger sawtooth.

Is it possible to return a custom error to the client that requested the transaction? How is the client supposed to know the reason that a transaction has not been processed?

I need to return an error from within the apply() method when the transaction cannot be completed due to any validation error, so the client that made the request can have some feedback about the error to show it to the user.

def apply(self, transaction, context):

In the examples I've checked the code raises an exception, but this ends the processor execution.

Any idea how can I do it?

klautern
  • 129
  • 3
  • 7
  • 26
  • ```raise``` keyword would've come in handy and also, read [this](https://stackoverflow.com/questions/1319615/proper-way-to-declare-custom-exceptions-in-modern-python#1319675) – Ghost Ops Aug 23 '21 at 06:26
  • What's your client? – Brian Destura Aug 23 '21 at 07:34
  • I've got 2 clients, one for python and one for javascript – klautern Aug 23 '21 at 08:06
  • 1
    If I raise an exception from within the apply method of the tx processor, the processor ends. I'm looking for the official way to reply from the validator to the client that the tx could not be completed for some reason. Something like modify the transaction object status sent by the validator to the apply method – klautern Aug 23 '21 at 08:06

3 Answers3

0

You can try something like this:

def apply(self, transaction, context):
    try:
        pass
        # your code
    except Exception as e:
        print(e)

Where instead of the print() call, send the e string to the client as it will contain the reason for the error.

Red
  • 26,798
  • 7
  • 36
  • 58
0

This can't be done by using the validator image as it is. You have to fork the https://github.com/hyperledger/sawtooth-core repo and implement your own logic in order to make the validator reply to the client in any custom case.

If you want to do that in order to avoid the infinite loop of the InvalidTransaction exceptions, you can build and use the validator from my fork https://github.com/charalarg/sawtooth-core instead of using the sawtooth validator docker image. Its the latest version of sawtooth (1.2.6) with a fix on the infinite loop bug.

I had the same problem and I was also trying to find a way to avoid transaction execution because of this bug but I ended up applying this fix. https://github.com/Remmeauth/sawtooth-core/pull/5.

Charalarg
  • 75
  • 1
  • 9
0

You could define your own custom error to let the client know exactly what went wrong:

class ValidationError(Exception):
    """Exception raised for validation errors.

    Attributes:
        reason -- reason of the error
        message -- explanation of the error
    """

    def __init__(self, reason, message="Validation failed"):
        self.reason = reason
        self.message = message
        super().__init__(self.message)

    def __str__(self):
        # the return value of this function will be the error message
        return f'{self.reason} -> {self.message}'

Then you can integrate that Error into your code like so for example:

def apply(self, transaction, context):
    try:
        if network_connection is False:
            raise ValidationError("Missing Network Connection")

        # your code here

        if success is False:
            raise ValidationError("Unknown reason")

    except Exception as e:
        print(e)

If, for example, network_connection is set to False before the execution of the apply() function, the message printed out with e will be:

ValidationError: Missing Network Connection -> Validation failed

This message can then be sent to the client.

Enoch
  • 344
  • 2
  • 6