如何从 puppeteer-sharp 中获取可读的 browser/page 错误?
How do I get readable browser/page errors out of 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 协议,因为我开始出现超时错误,然后出现错误抱怨网络套接字被破坏。
这似乎是人偶操纵者本身的问题:https://github.com/GoogleChrome/puppeteer/issues/3397
所以我的问题发生了,因为错误显然在 javascript 领域是不可序列化的,所以我们需要让浏览器 运行 一个函数来提取消息和我们需要的任何其他细节错误和 return that.
这就是我现在的工作方式:
_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。
The way it's supposed to be done atm is like this:
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);
});
我正在使用 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 协议,因为我开始出现超时错误,然后出现错误抱怨网络套接字被破坏。
这似乎是人偶操纵者本身的问题:https://github.com/GoogleChrome/puppeteer/issues/3397
所以我的问题发生了,因为错误显然在 javascript 领域是不可序列化的,所以我们需要让浏览器 运行 一个函数来提取消息和我们需要的任何其他细节错误和 return that.
这就是我现在的工作方式:
_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。
The way it's supposed to be done atm is like this:
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); });