include stack trace in JS function call log errors

This commit is contained in:
Karl Seguin
2025-06-02 15:09:18 +08:00
parent 9e834e0db5
commit a000dfe676

View File

@@ -1857,9 +1857,11 @@ pub fn Env(comptime State: type, comptime WebApis: type) type {
fn generateNamedIndexer(comptime Struct: type, template_proto: v8.ObjectTemplate) void {
if (@hasDecl(Struct, "named_get") == false) {
if (builtin.mode == .Debug and log.enabled(.unknown_prop, .debug)) {
if (comptime builtin.mode == .Debug) {
if (log.enabled(.unknown_prop, .debug)) {
generateDebugNamedIndexer(Struct, template_proto);
}
}
return;
}
const configuration = v8.NamedPropertyHandlerConfiguration{
@@ -2499,16 +2501,20 @@ fn Caller(comptime E: type, comptime State: type) type {
}
fn handleError(self: *Self, comptime Struct: type, comptime named_function: NamedFunction, err: anyerror, info: anytype) void {
if (builtin.mode == .Debug and log.enabled(.js, .warn) and @hasDecl(@TypeOf(info), "length")) {
const isolate = self.isolate;
if (comptime builtin.mode == .Debug and @hasDecl(@TypeOf(info), "length")) {
if (log.enabled(.js, .warn)) {
const args_dump = self.serializeFunctionArgs(info) catch "failed to serialize args";
log.warn(.js, "function call error", .{
.name = named_function.full_name,
.err = err,
.args = args_dump,
.stack = stackForLogs(self.call_arena, isolate) catch |err1| @errorName(err1),
});
}
}
const isolate = self.isolate;
var js_err: ?v8.Value = switch (err) {
error.InvalidArgument => createTypeException(isolate, "invalid argument"),
error.OutOfMemory => createException(isolate, "out of memory"),
@@ -3105,6 +3111,24 @@ fn jsStringToZig(allocator: Allocator, str: v8.String, isolate: v8.Isolate) ![]u
return buf;
}
fn stackForLogs(arena: Allocator, isolate: v8.Isolate) !?[]const u8 {
std.debug.assert(builtin.mode == .Debug);
const separator = log.separator();
var buf: std.ArrayListUnmanaged(u8) = .empty;
var writer = buf.writer(arena);
const stack_trace = v8.StackTrace.getCurrentStackTrace(isolate, 30);
const frame_count = stack_trace.getFrameCount();
for (0..frame_count) |i| {
const frame = stack_trace.getFrame(isolate, @intCast(i));
const script = try jsStringToZig(arena, frame.getScriptName(), isolate);
try writer.print("{s}{s}:{d}", .{ separator, script, frame.getLineNumber() });
}
return buf.items;
}
const NoopInspector = struct {
pub fn onInspectorResponse(_: *anyopaque, _: u32, _: []const u8) void {}
pub fn onInspectorEvent(_: *anyopaque, _: []const u8) void {}