如何调试返回‘Fulfilled with error’的Chainlink Functions请求?
问题:Chainlink Functions请求扣费但未收到API数据,执行状态显示Fulfilled with error
向Chainlink Functions的DON发送请求时,交易成功且订阅已扣费,但未收到API返回的数据。订阅管理器的「Recent Fulfillments」显示执行状态为「Fulfilled with error」,且DON未发起API调用(API端无新调用记录)。
已尝试的操作:
- 降低合约Gas用量,无效
- 该合约6个月前在Chainlink Functions Beta版本可正常运行
- 已按说明使用密钥管理器加密API密钥,源码无明显错误
相关信息:
- Chainlink Functions订阅(Mumbai网络,ID 888)
- Polygon Mumbai上的Functions消费者合约(地址:0xF26e7C782728767A8A4dC1a309aCbA5326731231)
请求所用JS脚本:
const plot = args[0]; var verifiedString = ""; var regex = /^\/{0,}(?:[^0-9`~!@#$%^&*()+\-_=[{\]}\\|'<,.>?/";:\u00a3\u00a7\u00ba\u00a9\u00ae\s]+[.\uff61\u3002\uff65\u30fb\uFE12\u17d5\u0589\u1362\u06d4\u1367\u0964][^0-9`~!@#$%^&*()+\-_=[{\]}\\|'<,.>?/";:\u00a3\u00a7\u00ba\u00a9\u00ae\s]+[.\uff61\u3002\uff65\u30fb\uFE12\u17d5\u0589\u1362\u06d4\u1367\u0964][^0-9`~!@#$%^&*()+\-_=[{\]}\\|'<,.>?/";:\u00a3\u00a7\u00ba\u00a9\u00ae\s]+|[^0-9`~!@#$%^&*()+\-_=[{\]}\\|'<,.>?/";:\u00a3\u00a7\u00ba\u00a9\u00ae\s]+([\u0020\u00a0][^0-9`~!@#$%^&*()+\-_=[{\]}\\|'<,.>?/";:\u00a3\u00a7\u00ba\u00a9\u00ae\s]+){1,3}[.\uff61\u3002\uff65\u30fb\uFE12\u17d5\u0589\u1362\u06d4\u1367\u0964][^0-9`~!@#$%^&*()+\-_=[{\]}\\|'<,.>?/";:\u00a3\u00a7\u00ba\u00a9\u00ae\s]+([\u0020\u00a0][^0-9`~!@#$%^&*()+\-_=[{\]}\\|'<,.>?/";:\u00a3\u00a7\u00ba\u00a9\u00ae\s]+){1,3}[.\uff61\u3002\uff65\u30fb\uFE12\u17d5\u0589\u1362\u06d4\u1367\u0964][^0-9`~!@#$%^&*()+\-_=[{\]}\\|'<,.>?/";:\u00a3\u00a7\u00ba\u00a9\u00ae\s]+([\u0020\u00a0][^0-9`~!@#$%^&*()+\-_=[{\]}\\|'<,.>?/";:\u00a3\u00a7\u00ba\u00a9\u00ae\s]+){1,3})$/; if (plot.length > 64) { throw Error(`Request Failed: Too many characters in request`) } // Check for regular expressions if (!regex.test(plot)) { throw Error(`Request Failed: Not a correctly formatted plot name`) } // build HTTP request objects // API call to GET the words address location info using the supplied words address in any language. // If the supplied words address is incorrect the API will revert with an error. const request = Functions.makeHttpRequest({ url: `https://api.what3words.com/v3/convert-to-coordinates`, headers: { "X-Api-Key": secrets.apiKey }, params: { words: plot, }, }) // Wait for all requests to finish const response = await request; // Verify if there are any errors in responses if (response.error || response.Response === "Error") { throw Error(`Request Failed: Code: ${response.code} Message: ${response.message}`); } else if (response["data"]["language"] != "en") { const lat = response["data"]["coordinates"]["lat"] const lng = response["data"]["coordinates"]["lng"] const coordinates = `${lat},${lng}` const enRequest = Functions.makeHttpRequest({ url: `https://api.what3words.com/v3/convert-to-3wa`, // Get a free API key from https://accounts.what3words.com/create-api-key/ headers: { "X-Api-Key": secrets.apiKey }, params: { coordinates: coordinates, language: "en", }, }) const enResponse = await enRequest; if (enResponse.error || enResponse.Response === "Error") { throw Error(`Request Failed: Code: ${enResponse.code} Message: ${enResponse.message}`); } else if (enResponse["data"]["language"] != "en") { throw Error(`Request Failed: Code: 400 Message: BadLanguage`); } else { verifiedString = enResponse.data.words; } } else { verifiedString = response.data.words; } // throw an error if verifiedString is empty if (verifiedString.length == 0) { throw Error(`Request Failed: API result empty.`) } return Functions.encodeString(`${verifiedString}`)
排查与解决方案
1. 检查正则表达式兼容性
Chainlink Functions从Beta到正式版可能更新了JS运行环境,你脚本中的正则包含大量Unicode转义字符,可能存在解析或执行错误。建议:
- 拆分正则验证逻辑,先检查格式结构(三个点分隔的部分),再验证字符规则
- 在本地Node.js环境(匹配Chainlink Functions使用的版本)中测试正则,确认
regex.test(plot)的行为符合预期
2. 确认密钥解密状态
虽然已加密API密钥,但正式版可能调整了解密逻辑。可以:
- 在脚本开头添加日志:
console.log("API Key loaded:", secrets.apiKey ? "Yes" : "No"),在订阅管理器的执行日志中查看密钥是否正常加载 - 重新生成并加密API密钥,确保流程符合当前Chainlink Functions要求
3. 修复异步执行逻辑
脚本使用了顶级await,部分环境可能不支持,建议包裹在异步函数中:
async function run() { // 原脚本所有内容 } return run();
4. 查看详细执行日志
在订阅管理器的「Recent Fulfillments」中点击具体执行记录,查看错误详情,这会直接显示脚本失败原因(比如正则错误、密钥未加载、语法问题等)
5. 适配正式版API差异
Chainlink Functions正式版可能修改了Functions.makeHttpRequest的返回格式,比如原Beta版的response.Response字段可能已变更。建议:
- 将错误判断逻辑改为检查
response.status >= 400 - 本地模拟请求返回,验证错误处理逻辑的正确性
内容的提问来源于stack exchange,提问作者Vince Reid
相关产品推荐
相关产品推荐

