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

AWS CloudWatch Canary(Node.js Puppeteer):优化XML文本校验错误提示

问题描述

通过AWS CloudWatch Canary的GUI生成代码并适配后,用于检测返回XML格式内容的网页,目标是校验ABC标签的value属性中是否存在特定字符串。当前代码在字符串存在时能正常通过,但不存在时会抛出超时错误,而非明确的“未找到”提示,错误信息如下:

TimeoutError: Waiting for selector .//ABC[@value='searchingforthistext'] failed: Waiting failed: 5000ms exceeded Stack: TimeoutError: Waiting for selector .//ABC[@value='searchingforthistext'] failed: Waiting failed: 5000ms exceeded at Timeout. (/opt/nodejs/node_modules/puppeteer-core/lib/cjs/puppeteer/common/WaitTask.js:65:32) at listOnTimeout (node:internal/timers:559:17) at processTimers (node:internal/timers:502:7)

目标XML格式:

<Description>
  <XYZ code="100" label="some text here" value="22"/>
  <ABC code="110" label="some text here" value="searchingforthistext"/>
</Description>

现有Canary代码:

const synthetics = require('Synthetics');
const log = require('SyntheticsLogger');
const syntheticsConfiguration = synthetics.getConfiguration();

const flowBuilderBlueprint = async function () {
    // INSERT URL here
    let url = "https://something.com/mypage";

    syntheticsConfiguration.setConfig({
        includeRequestHeaders: true, // Enable if headers should be displayed in HAR
        includeResponseHeaders: true, // Enable if headers should be displayed in HAR
        restrictedHeaders: [], // Value of these headers will be redacted from logs and reports
        restrictedUrlParameters: [] // Values of these url parameters will be redacted from logs and reports
    });
    let page = await synthetics.getPage();

    // Navigate to the initial url
    await synthetics.executeStep('navigateToUrl', async function (timeoutInMillis = 30000) {
        await page.goto(url, {waitUntil: ['load', 'networkidle0'], timeout: timeoutInMillis});
    });

    // Execute customer steps
    await synthetics.executeStep('verifyText', async function () {
      const exists = await page.waitForXPath("//ABC[@value='searchingforthistext']", { timeout: 5000 } );
      if (exists) {
        console.log('text found')
      } else {
        console.log('text not found')
      }
    });
};

exports.handler = async () => {
    return await flowBuilderBlueprint();
};
解决方案

问题核心是page.waitForXPath的特性:当XPath匹配不到元素时,它会直接抛出超时错误,不会进入后续的if-else判断。要实现明确的结果提示,可通过以下方式修改:

修改思路

  1. 改用page.$x直接查询元素,通过返回数组的长度判断是否匹配,避免超时等待
  2. 使用CloudWatch专用日志工具SyntheticsLogger记录结果,确保日志能被正确采集
  3. 未找到目标时主动调用synthetics.addExecutionError标记Canary失败,生成直观的错误报告

修改后的完整代码

const synthetics = require('Synthetics');
const log = require('SyntheticsLogger');
const syntheticsConfiguration = synthetics.getConfiguration();

const flowBuilderBlueprint = async function () {
    let url = "https://something.com/mypage";

    syntheticsConfiguration.setConfig({
        includeRequestHeaders: true,
        includeResponseHeaders: true,
        restrictedHeaders: [],
        restrictedUrlParameters: []
    });
    let page = await synthetics.getPage();

    await synthetics.executeStep('navigateToUrl', async function (timeoutInMillis = 30000) {
        await page.goto(url, {waitUntil: ['load', 'networkidle0'], timeout: timeoutInMillis});
    });

    await synthetics.executeStep('verifyTargetValue', async function () {
        // 直接查询匹配的元素数组
        const matchedElements = await page.$x("//ABC[@value='searchingforthistext']");
        
        if (matchedElements.length > 0) {
            log.info('目标字符串已找到,校验通过');
        } else {
            log.error('未找到目标字符串,校验失败');
            // 主动标记Canary执行失败,自定义错误信息
            synthetics.addExecutionError('ABC标签的value属性中未找到目标字符串');
        }
    });
};

exports.handler = async () => {
    return await flowBuilderBlueprint();
};

关键修改说明

  • page.$x的优势:直接返回匹配的元素数组,不会抛出异常,能立即判断结果,避免不必要的超时等待
  • 日志规范:用log.info/log.error代替console.log,确保日志能在CloudWatch Synthetics控制台中正常显示
  • 失败标记:调用synthetics.addExecutionError会明确将Canary状态标记为失败,同时在报告中展示自定义错误信息,比默认超时错误更直观

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 23:27:03