Throw `Error` objects, not strings, so you keep a stack. Subclass for typed handling and use `cause` to keep the original.
class RpcError extends Error {
constructor(msg, opts) { super(msg, opts); this.name = "RpcError"; }
}
throw new RpcError("eth_call failed", { cause: e });Catch narrowly: swallowing every error hides bugs and makes support impossible.