How to get the hash of a reverted transaction in ethers.js

Hi, I'm making a call to a contract of mine using ethers.js. I'm trying to get the error message to display it to the user of my DApp. But I can't get the error because I can't access to the transaction hash.

export const startPreorderAPI = async (ethers: Wallet, from: string, preorderID: string) => {
    let trx = null;
    try {
        const calendarInstance = getCalendarInstance(ethers);
        const preorderInformation = await calendarInstance
            .preorderInfo(preorderID)
        console.log(preorderInformation);
        trx = await calendarInstance
            .startLendingPeriod(preorderID)
        trx = await trx.wait();
        console.log(trx);
    } catch (e: any) {
        console.log(e);
    }
}

This is my error. And from the console "e" does not contain any transaction hash. What am I doing wrong?

1 Like

If the tx get mined and fail it doesn't throw any error in your js script.

1 Like

Continuing the previous answer, the code in your try clause may fail for a number of other reasons, for example, as a result of ethers.js internal timeout, while the transaction is still pending in the mempool.

One option for handling it in your script is as follows:

try {
    ...
    receipt = await trx.wait();
    return receipt;
} catch (error) {
    console.log(error.message);
    const receipt = await getTransactionReceipt();
    if (receipt)
        return receipt;
}

Where function getTransactionReceipt is implemented as follows:

async function scan(message) {
    process.stdout.write(message);
    return await new Promise(function(resolve, reject) {
        process.stdin.resume();
        process.stdin.once("data", function(data) {
            process.stdin.pause();
            resolve(data.toString().trim());
        });
    });
}

async function getTransactionReceipt() {
    while (true) {
        const hash = await scan("Enter transaction-hash or leave empty to retry: ");
        if (/^0x([0-9A-Fa-f]{64})$/.test(hash)) {
            const receipt = await web3.eth.getTransactionReceipt(hash);
            if (receipt)
                return receipt;
            console.log("Invalid transaction-hash");
        }
        else if (hash) {
            console.log("Illegal transaction-hash");
        }
        else {
            return null;
        }
    }
}

Then your script's user will need to manually obtain the transaction hash from etherscan or similar.

The suggestion above is based on web3.js, so you'll need to adjust it to ethers.js.

Thank you for the solution provided! What's the "scan" function? I can't find it using google. I need it since I'm having difficulties at retrieving the hash of the transaction

Sorry, forgot to paste that; answer updated.

Note that this function doesn't retrieve the hash of the transaction; it only allows you to enter it manually.
You'll still need to retrieve it - also manually - from etherscan or similar.
As I wrote in the previous answer, it might not even be available yet (at that specific point in time).