trufflesuite / drizzle

Reactive Ethereum dapp UI suite
905 stars 235 forks source link

Catching "authentication needed: password or unlock" error with drizzle? #27

Open KorbinianK opened 4 years ago

KorbinianK commented 4 years ago

How do I catch the Error: Returned error: authentication needed: password or unlock with drizzle correctly?

Note: I am not using MetaMask but a customProvider in drizzleOptions. I know MetaMask handles this usually.

If a transaction is sent and the account is not unlocked, there is no way to catch the error with drizzle. The transaction only gets a "hash" like TEMP_1569148036244 on the transactionStack, but never gets an entry in transactions in the state. In the console, Websocket throws the error with unlock required. (see above)

So I cannot get the transactions[txHash].status and show the user the correct feedback. Any suggestions?

handleApprove(event) {
    event.preventDefault();
    const { drizzle, drizzleState } = this.props;

    drizzle.contracts.Token.methods.approve.cacheSend(this.contracts.Exchange.address, 100000, { from: drizzleState.accounts[0] });

    this.setState({ stackId });
  }
  getTxStatus = () => {
    const { transactions, transactionStack } = this.props.drizzleState;
    const txHash = transactionStack[this.state.stackId];
    if (!txHash || transactions[txHash]) return null;
    return `Transaction status: ${transactions[txHash].status}`;
  };
<button
    key="approve"
    type="button"
    onClick={this.handleApprove}
    Approve
</button>
{this.getTxStatus()}
cds-amal commented 4 years ago

@KorbinianK do you have a sample repo you could share? I'll try to reproduce it in the mean time.

cds-amal commented 4 years ago

This is an interesting use case and I think Drizzle should forward errors from any provider it is using and resolve failed transactions from our outstanding stack. @DiscRiskandBisque, @adrianmcli, what do you think?

adrianmcli commented 4 years ago

@KorbinianK A reproduction repo would really help, but also I wanted to ask what provider you are using?

KorbinianK commented 4 years ago

@adrianmcli @cds-amal I created a project based on the drizzlebox to replicate this issue, and it worked. I correctly got a transaction in the stack:

Transactions: {…}
​   TEMP_1569518579147: {…}
   error: Object { message: "Returned error: authentication needed: password or unlock" }
   status: "error"

Then I tried in my original project again, and it worked there too. I have no idea what caused the transaction to be missing previously.

Setup: Local PoA testchain with a few sealer nodes. Custom provider as per last PR that added this. I will keep an eye on this.

However: Now that it is working, as @cds-amal posted, the transactions stay in transactionStack, some handling would be useful. For now I use a try/catch around personal.unlock and catch the error before it goes to the drizzle stack.