lens-protocol / lens-sdk

The official SDK to interact with the Lens Protocol
https://docs.lens.xyz/docs/what-is-lens
MIT License
230 stars 71 forks source link

In the useOpenAction react hook, when the user doesn't have enough funds to collect, an unhandled promise is being thrown instead of being handled by the SDK #808

Open pradel opened 5 months ago

pradel commented 5 months ago

Describe the bug

In the useOpenAction hook, the SDK does not handle properly when the user doesn't have the funds to collect. I published a post that can be collected using 0.01 WMATIC, when a user without enough funds in his wallet, an unhandled promise is thrown instead of being handled with the result.isFailure.

Uncaught (in promise) ValidationError: You do not have enough balance to collect this publication.

To Reproduce

I am having an issue with the following code

const { execute: collect, loading: loadingCollect } = useOpenAction({
    action: {
      kind: OpenActionKind.COLLECT,
    },
  });

 const onCollect = async () => {
// The collect call is currently throwing, the error should be in result.error instead
const result = await collect({
      publication,
    });
    if (result.isFailure()) {
      toast({
        title: "Failed to collect",
        description: result.error.message,
        variant: "destructive",
      });
      return;
    }
}

Expected behaviuor

The error should be catched and returned by the isFailure function

If using the React bindings, what is the essence of your React app?

Version of the packages you are using

"@lens-protocol/client": "2.0.0-alpha.27",
    "@lens-protocol/metadata": "1.1.5",
    "@lens-protocol/react-web": "2.0.0-alpha.27",
    "@lens-protocol/wagmi": "3.0.0-alpha.24",
pradel commented 5 months ago

Probably related to the same root issue but with the same code I get the following unhandled promise rejection when trying to collect multiple times from the same profile.

ValidationError: Profile XXX has already acted on XXX in publication XXX
cesarenaldi commented 5 months ago

@pradel thank you for raising this. Indeed the first error should be returned as Failure<InsufficientFundsError> like you said.

The second one is a different thing though. This is an API restriction that allows to use gasless collect only once for a given publication (for the same Profile).

We should model this better and not throw.

pradel commented 5 months ago

@cesarenaldi as one connected with just a wallet (no Lens profile) can collect many items I think the behavior with a Lens profile should be the same and there should be no limitations for it.

cesarenaldi commented 5 months ago

@pradel this is absolutely true. The idea behind the error:

ValidationError: Profile XXX has already acted on XXX in publication XXX

is that the first collect for a Profile is sponsored by the Lens API (i.e. covers tx gas costs), any subsequent must be covered with own funds (like the case of just a wallet that collects, they always have to pay for gas themselves). It's to avoid abuse more than anything else.

We have intention to support this mechanics in the SDK with a specific error type so that consumers can detect this scenario and switch to self-funded collect (i.e. sponsored flag set to false). Or even have the SDK takes this decision internally.

We just didn't get to this yet, as until now, it was deemed low priority.

So to understand how urgent this is, is this a primary concern for the UX you are working on? Do you see Profiles collecting often the same exact publication?

pradel commented 5 months ago

I don't have production results to know if many people are doing this, but it came up while doing tests on testnet. Not sure people will do it. Once we push the app to prod I can add some tracking to see how many people are affected by this error. It would be great to have the SDK return the error instead of throwing it so we can show a toast with the error for now.

cesarenaldi commented 5 months ago

That would be a good interim step we can action pretty quick.

The retry with self-funded is where we need to change the underlying GQL mutation and need a little thinking on how to perform this check later at "broadcast time".

Regarding the very first error:

Uncaught (in promise) ValidationError: You do not have enough balance to collect this publication.

Do you have a publication ID (and where: Testnet or Mainnet)?

pradel commented 5 months ago

@cesarenaldi it was on testnet but it seems that the error is not happening with our production build. Pretty weird, will try again next weekend to see what's going on.