You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Cloudflare Workers运行Web3+Wasm追踪ERC20代币时出现Hanging Promise Canceled错误求助

Cloudflare Workers + Rust/Wasm: Fixing "A hanging Promise was canceled" Error when Fetching ERC20 Total Supply

我最近在开发一个Cloudflare Workers程序,用来追踪ERC20代币的流通量,算是学习Web3和Wasm的实践项目。原本以为实现难度不大,但现在90%的时间都耗在一个棘手的错误上:A hanging Promise was canceled。

官方对这个错误的说明是:

当Worker运行时等待JavaScript中的Promise完成,但检测到由于该Promise请求上下文相关的所有代码和事件已执行完毕,导致该Promise永远无法完成时触发。

我在网上查找了相关资料,但似乎我的错误类型和常见情况不太一样。下面是可复现问题的代码片段:

Rust代码

mod erc20_abi;
use erc20_abi::ERC20_ABI;
use cfg_if::cfg_if;
use ethers::{
    contract::Contract,
    core::{abi::Abi, types::Address},
    prelude::{AbiError, U256},
    providers::{Http, Provider},
};
use num_format::{Locale, ToFormattedString};
use std::convert::TryFrom;
use wasm_bindgen::prelude::*;

cfg_if! {
    // When the `wee_alloc` feature is enabled, use `wee_alloc` as the global
    // allocator.
    if #[cfg(feature = "wee_alloc")] {
        extern crate wee_alloc;
        #[global_allocator]
        static ALLOC: wee_alloc::WeeAlloc = wee_alloc::WeeAlloc::INIT;
    }
}

#[wasm_bindgen]
pub async fn handle() -> String {
    let web3_ethereum = Provider::<Http>::try_from(WEB3_URL_ETHEREUM).unwrap();
    let abi: Abi = serde_json::from_str(ERC20_ABI).unwrap();
    let token_contract_ethereum = Contract::new(parse_address(ADDRESS_ETH), abi, web3_ethereum);

    let convert_wei_to_decimal = |bignumber: U256| -> String {
        (bignumber.as_u128() / u128::pow(10, 18)).to_formatted_string(&Locale::en)
    };

    // 我认为此处是问题所在,因为直接返回字符串时程序运行正常
    let total_supply_ethereum = token_contract_ethereum
        .method::<_, U256>("totalSupply", ())
        .unwrap()
        .call()
        .await
        .unwrap();

    convert_wei_to_decimal(total_supply_ethereum)
}

fn parse_address(address: &str) -> Address {
    address.parse::<Address>().unwrap()
}

Workers.js代码

addEventListener('fetch', (event) => {
    event.respondWith(handleRequest(event.request))
})

const { handle } = wasm_bindgen;
const instance = wasm_bindgen(wasm);

/**
 * Fetch and log a request
 * @param {Request} request
 */
async function handleRequest(request) {
    await instance;
    const output = await handle();
    let res = new Response(output, { status: 200 });
    res.headers.set('Content-type', 'text/html');
    return res;
}

Cargo.toml配置

[package]
name = "circulating-supply"
version = "0.1.0"
license = "GPL-3.0-or-later"
edition = "2018"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[lib]
crate-type = ["cdylib", "rlib"]

[profile.release]
opt-level = 's' # Optimize for size.
lto = true
panic = "abort"
codegen-units = 1

[dependencies]
ethers = { git = "https://github.com/gakonst/ethers-rs" }
serde_json = "1.0.68"
num-format = "0.4.0"
cfg-if = "1.0.0"
wee_alloc = { version = "0.4.5", optional = true }
wasm-bindgen = "0.2.78"
wasm-bindgen-futures = "0.4.28"
js-sys = "0.3.55"

使用wrangler dev编译程序一切正常,但访问http://127.0.0.1:8787时会触发Error 1101,恳请各位帮忙排查解决这个问题!

内容的提问来源于stack exchange,提问作者Corfucinas

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.30 17:37:46