如何从木偶锐化中获得可读的浏览器/页面错误?

时间:2019-07-09 19:14:03

标签: c# error-handling puppeteer puppeteer-sharp

我正在使用puppeteer-sharp将某些页面呈现为PDF。我想知道页面是否在运行时在浏览器中呈现任何问题,所以我设置了一些事件处理程序:

_page.Error += (sender, args) =>
{
    _logger.LogCritical(args.Error);
};

_page.PageError += (sender, args) =>
{
    _logger.LogError(args.Message);
};

_page.Console += (sender, args) =>
{
    switch (args.Message.Type)
    {
        case ConsoleType.Error:
            _logger.LogError(args.Message.Text);
            break;
        case ConsoleType.Warning:
            _logger.LogWarning(args.Message.Text);
            break;
        default:
            _logger.LogInformation(args.Message.Text);
            break;
    }
};

页面出现错误时,args.Message.Text似乎只包含"ERROR JSHandle@error"。这不是很有帮助。

我在页面上测试了正常的console.log,并且记录良好,这似乎是错误的问题。

是否需要做一些事情才能使这些错误更易读懂?

更新:我尝试访问args.Message.Args并在这些args上使用JsonValueAsync(),但这似乎会引起一些异步怪异,从而破坏了devtools协议,因为我开始遇到超时错误,然后抱怨网络套接字的错误被破坏。

这似乎是p操纵者本身的问题:https://github.com/GoogleChrome/puppeteer/issues/3397

1 个答案:

答案 0 :(得分:1)

所以发生了我的问题,因为错误显然无法在javascript领域中进行序列化,因此我们需要让浏览器运行一个函数来从错误中提取消息和我们需要的其他详细信息,然后将其返回。

这就是现在为我工作的内容:

_page.Console += async (sender, args) =>
{
    switch (args.Message.Type)
    {
        case ConsoleType.Error:
            try
            {
                var errorArgs = await Task.WhenAll(args.Message.Args.Select(arg => arg.ExecutionContext.EvaluateFunctionAsync("(arg) => arg instanceof Error ? arg.message : arg", arg)));
                _logger.LogError($"{args.Message.Text} args: [{string.Join<object>(", ", errorArgs)}]");
            }
            catch { }
            break;
        case ConsoleType.Warning:
            _logger.LogWarning(args.Message.Text);
            break;
        default:
            _logger.LogInformation(args.Message.Text);
            break;
    }
};

我从一个伪造者here的评论中得到了这个想法,并将其移植到pupeteer-sharp中。

  

应该在atm上完成的方式是这样的:

page.on('console', async msg => {
  // serialize my args the way I want
  const args = await Promise.all(msg.args.map(arg => arg.executionContext().evaluate(arg => {
    // I'm in a page context now. If my arg is an error - get me its message.
    if (arg instanceof Error)
      return arg.message;
    // return arg right away. since we use `executionContext.evaluate`, it'll return JSON value of
    // the argument if possible, or `undefined` if it fails to stringify it.
    return arg;
  }, arg)));
  console.log(...args);
});