Shopify Webhook操作遇‘Unexpected end of JSON input’错误排查请求
Shopify Webhook 注册与列表获取报错分析与解决
问题背景
我开发了一款Shopify应用,用于注册Webhook并获取所有Webhook列表,核心代码如下(路径:/server/middleware/auth.js):
const webhook = new Webhook({ session: session }); webhook.topic = "products/update"; webhook.address = "https://api.service.co/items/update"; webhook.format = "json"; console.log("registering products/update"); try { await webhook.save({ update: true, }); } catch (error) { console.log(error); } const webhookSecond = new Webhook({ session: session }); webhookSecond.topic = "products/create"; webhookSecond.address = "https://api.service.co/items/webhooks"; webhookSecond.format = "json"; console.log("registering products/create"); try { await webhookSecond.save({ update: true, }); } catch (error) { console.log(error); } console.log("getting all webhooks"); try { let webhooks = await Webhook.all({ session: session, }); console.log(webhooks); } catch (error) { console.log(error); }
这段代码在我的开发店铺运行正常,但在第三方客户店铺执行时,多次触发如下错误:
HttpRequestError: Failed to make Shopify HTTP request: FetchError: invalid json response body at https://shopname.myshopify.com/admin/api/2022-04/webhooks.json reason: Unexpected end of JSON input
应用权限范围为:read_checkouts, read_orders, read_inventory, read_products, read_customers,即使单独调用Webhook.all也会报错。
错误成因分析
- 核心权限缺失:当前申请的权限中没有
read_webhooks和write_webhooks,调用Webhook相关API(注册、查询列表)必须拥有对应权限。开发店铺属于自己的测试环境,权限限制较宽松,但第三方店铺严格遵循应用申请的权限列表,此时API会返回403等非JSON格式的错误响应,客户端解析时就会抛出JSON格式错误。 - API版本过旧:使用的2022-04版本API已发布较长时间,部分Shopify店铺可能对旧版本API的支持有所调整,导致响应数据异常。
- 网络传输异常:第三方店铺服务器与你的应用之间的网络不稳定,导致响应数据被截断,JSON解析时因内容不完整报错。
解决办法
- 补充Webhook权限:修改应用的权限配置,添加
read_webhooks和write_webhooks权限,然后引导客户重新授权应用。这是解决问题的关键,没有对应权限会直接导致API请求失败并返回非JSON响应。 - 升级API版本:将API版本升级到较新的稳定版本(如2024-01),规避旧版本的兼容性问题。
- 增强错误日志:在捕获错误时,增加对响应状态码和原始内容的打印,精准定位问题:
catch (error) { console.log('请求状态码:', error.response?.status); console.log('原始响应内容:', error.response?.data); console.log(error); }
- 优化Webhook注册逻辑:合并重复代码,增加幂等性检查(比如先查询是否已存在对应topic的Webhook,再决定是否注册),减少不必要的API调用:
// 封装Webhook注册函数 async function registerWebhook(session, topic, address) { const existingWebhooks = await Webhook.all({ session }); const exists = existingWebhooks.some(wh => wh.topic === topic && wh.address === address); if (exists) { console.log(`Webhook ${topic} already exists, skip registration`); return; } const webhook = new Webhook({ session }); webhook.topic = topic; webhook.address = address; webhook.format = "json"; console.log(`registering ${topic}`); try { await webhook.save({ update: true }); } catch (error) { console.log(`Failed to register ${topic}:`, error); } } // 调用封装函数 await registerWebhook(session, "products/update", "https://api.service.co/items/update"); await registerWebhook(session, "products/create", "https://api.service.co/items/webhooks");
内容的提问来源于stack exchange,提问作者Pavel Shepelenko
相关产品推荐
相关产品推荐

