diff --git a/src/browser/page.zig b/src/browser/page.zig index 8786f229..21faa208 100644 --- a/src/browser/page.zig +++ b/src/browser/page.zig @@ -151,16 +151,29 @@ pub const Page = struct { const self: *Page = @ptrCast(@alignCast(ctx)); const base = if (self.current_script) |s| s.src else null; - const file_src = blk: { + const src = blk: { if (base) |_base| { break :blk try URL.stitch(self.arena, specifier, _base, .{}); } else break :blk specifier; }; - if (self.module_map.get(file_src)) |module| return module; + if (self.module_map.get(src)) |module| { + log.debug(.http, "fetching module", .{ + .src = src, + .cached = true, + }); + return module; + } + + log.debug(.http, "fetching module", .{ + .src = src, + .base = base, + .cached = false, + .specifier = specifier, + }); const module = try self.fetchData(specifier, base); - if (module) |_module| try self.module_map.putNoClobber(self.arena, file_src, _module); + if (module) |_module| try self.module_map.putNoClobber(self.arena, src, _module); return module; } @@ -461,9 +474,9 @@ pub const Page = struct { }; var script_source: ?[]const u8 = null; + defer self.current_script = null; if (script.src) |src| { self.current_script = script; - defer self.current_script = null; // https://html.spec.whatwg.org/multipage/webappapis.html#fetch-a-classic-script script_source = (try self.fetchData(src, null)) orelse { @@ -507,8 +520,18 @@ pub const Page = struct { var origin_url = &self.url; const url = try origin_url.resolve(arena, res_src); - log.debug(.http, "fetching script", .{ .url = url }); - errdefer |err| log.err(.http, "fetch error", .{ .err = err, .url = url }); + var status_code: u16 = 0; + log.debug(.http, "fetching script", .{ + .url = url, + .src = src, + .base = base, + }); + + errdefer |err| log.err(.http, "fetch error", .{ + .err = err, + .url = url, + .status = status_code, + }); var request = try self.newHTTPRequest(.GET, &url, .{ .origin_uri = &origin_url.uri, @@ -521,7 +544,8 @@ pub const Page = struct { var header = response.header; try self.session.cookie_jar.populateFromResponse(&url.uri, &header); - if (header.status < 200 or header.status > 299) { + status_code = header.status; + if (status_code < 200 or status_code > 299) { return error.BadStatusCode; } @@ -539,7 +563,7 @@ pub const Page = struct { log.info(.http, "fetch complete", .{ .url = url, - .status = header.status, + .status = status_code, .content_length = arr.items.len, }); return arr.items; @@ -1002,6 +1026,9 @@ const Script = struct { defer try_catch.deinit(); const src = self.src orelse "inline"; + + log.debug(.browser, "executing script", .{ .src = src, .kind = self.kind }); + _ = switch (self.kind) { .javascript => page.main_context.exec(body, src), .module => blk: { diff --git a/src/runtime/js.zig b/src/runtime/js.zig index 2ed89594..36aab531 100644 --- a/src/runtime/js.zig +++ b/src/runtime/js.zig @@ -1158,7 +1158,7 @@ pub fn Env(comptime State: type, comptime WebApis: type) type { } if (!js_value.isArray()) { - return .{.invalid = {}}; + return .{ .invalid = {} }; } // This can get tricky. @@ -1227,12 +1227,25 @@ pub fn Env(comptime State: type, comptime WebApis: type) type { // const referrer_module = if (referrer) |ref| v8.Module{ .handle = ref } else null; const module_loader = self.module_loader; const source = module_loader.func(module_loader.ptr, specifier) catch |err| { - log.err(.js, "resolve module fetch error", .{ .specifier = specifier, .err = err }); + log.err(.js, "resolve module fetch", .{ + .err = err, + .specifier = specifier, + }); return null; } orelse return null; + var try_catch: TryCatch = undefined; + try_catch.init(self); + defer try_catch.deinit(); + const m = compileModule(self.isolate, source, specifier) catch |err| { - log.err(.js, "resolve module compile error", .{ .specifier = specifier, .err = err }); + log.err(.js, "resolve module compile", .{ + .specifier = specifier, + .stack = try_catch.stack(self.context_arena) catch null, + .src = try_catch.sourceLine(self.context_arena) catch "err", + .line = try_catch.sourceLineNumber() orelse 0, + .exception = (try_catch.exception(self.context_arena) catch @errorName(err)) orelse @errorName(err), + }); return null; }; return m.handle; @@ -1547,6 +1560,20 @@ pub fn Env(comptime State: type, comptime WebApis: type) type { return try valueToString(allocator, s, js_context.isolate, js_context.v8_context); } + // the caller needs to deinit the string returned + pub fn sourceLine(self: TryCatch, allocator: Allocator) !?[]const u8 { + const js_context = self.js_context; + const msg = self.inner.getMessage() orelse return null; + const sl = msg.getSourceLine(js_context.v8_context) orelse return null; + return try jsStringToZig(allocator, sl, js_context.isolate); + } + + pub fn sourceLineNumber(self: TryCatch) ?u32 { + const js_context = self.js_context; + const msg = self.inner.getMessage() orelse return null; + return msg.getLineNumber(js_context.v8_context); + } + // a shorthand method to return either the entire stack message // or just the exception message // - in Debug mode return the stack if available