Skip to content

getContractError can loose the error cause when a custom provider is used #4387

@alcuadrado

Description

@alcuadrado

Check existing issues

Viem Version

2.47.1

Current Behavior

When interacting with a contract, the function getContractError can loose the error cause when using a custom provider. The error returned by it is correct in general, but it can loose track of the original error, making debugging harder.

Expected Behavior

The error returned by getContractError should have the right cause.

Steps To Reproduce

Here's a self-contained minimal repro with viem@2.47.1:

import { createWalletClient, getContract, custom, parseAbi } from "viem";
import { mainnet } from "viem/chains";

// A mock custom provider that throws this error for everything except eth_chainId
const executionErrorInCustomProviderWithCode3: any = new Error(
  `Execution error in custom provider`,
);
executionErrorInCustomProviderWithCode3.name = "CustomProviderExecutionError";
// ABI encoded "Error(string)" of "reverted"
executionErrorInCustomProviderWithCode3.data =
  "0x08c379a0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000087265766572746564000000000000000000000000000000000000000000000000";
executionErrorInCustomProviderWithCode3.code = 3;

const ethereumProvider = {
  async request({ method }: { method: string }) {
    console.log("Provider called with method:", method);
    if (method === "eth_chainId") {
      return "0x1";
    }

    throw executionErrorInCustomProviderWithCode3;
  },
};

const abi = parseAbi([
  "function transfer(address to, uint256 amount) returns (bool)",
]);

const sender = "0x1234567890123456789012345678901234567890";

const client = createWalletClient({
  chain: mainnet,
  transport: custom(ethereumProvider),
  account: sender,
});

const contract = getContract({
  address: "0x1111111111111111111111111111111111111111",
  abi,
  client,
});

try {
  await contract.write.transfer([
    "0x2222222222222222222222222222222222222222",
    0n,
  ]);
} catch (error: any) {
  console.log("error.name", error.name);
  console.log("error.cause?.name", error.cause?.name);

  // This should be CustomProviderExecutionError, but is `undefined`
  console.log("error.cause?.cause?.name", error.cause?.cause?.code);
  console.log();
  console.log();
  console.log(error);
}

Link to Minimal Reproducible Example

No response

Anything else?

Sending a PR to fix it in a few minutes

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions