Skip to content

Commit 5483c52

Browse files
authored
Merge pull request #771 from lightpanda-io/http_request_fail
Emit http_request_fail notification
2 parents f12e9b6 + 2b48902 commit 5483c52

File tree

7 files changed

+72
-4
lines changed

7 files changed

+72
-4
lines changed

src/browser/page.zig

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,8 @@ pub const Page = struct {
247247
.content_type = content_type,
248248
.charset = mime.charset,
249249
.url = request_url,
250+
.method = opts.method,
251+
.reason = opts.reason,
250252
});
251253

252254
if (!mime.isHTML()) {
@@ -597,6 +599,10 @@ pub const Page = struct {
597599
// The page.arena is safe to use here, but the transfer_arena exists
598600
// specifically for this type of lifetime.
599601
pub fn navigateFromWebAPI(self: *Page, url: []const u8, opts: NavigateOpts) !void {
602+
log.debug(.browser, "delayed navigation", .{
603+
.url = url,
604+
.reason = opts.reason,
605+
});
600606
self.delayed_navigation = true;
601607
const arena = self.session.transfer_arena;
602608
const navi = try arena.create(DelayedNavigation);

src/browser/xhr/xhr.zig

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -338,7 +338,11 @@ pub const XMLHttpRequest = struct {
338338
// dispatch request event.
339339
// errors are logged only.
340340
fn dispatchEvt(self: *XMLHttpRequest, typ: []const u8) void {
341-
log.debug(.script_event, "dispatch event", .{ .type = typ, .source = "xhr" });
341+
log.debug(.script_event, "dispatch event", .{
342+
.type = typ,
343+
.source = "xhr",
344+
.url = self.url,
345+
});
342346
self._dispatchEvt(typ) catch |err| {
343347
log.err(.app, "dispatch event error", .{ .err = err, .type = typ, .source = "xhr" });
344348
};
@@ -358,7 +362,11 @@ pub const XMLHttpRequest = struct {
358362
typ: []const u8,
359363
opts: ProgressEvent.EventInit,
360364
) void {
361-
log.debug(.script_event, "dispatch progress event", .{ .type = typ, .source = "xhr" });
365+
log.debug(.script_event, "dispatch progress event", .{
366+
.type = typ,
367+
.source = "xhr",
368+
.url = self.url,
369+
});
362370
self._dispatchProgressEvent(typ, opts) catch |err| {
363371
log.err(.app, "dispatch progress event error", .{ .err = err, .type = typ, .source = "xhr" });
364372
};

src/cdp/cdp.zig

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -412,11 +412,13 @@ pub fn BrowserContext(comptime CDP_T: type) type {
412412
}
413413

414414
pub fn networkEnable(self: *Self) !void {
415+
try self.cdp.browser.notification.register(.http_request_fail, self, onHttpRequestFail);
415416
try self.cdp.browser.notification.register(.http_request_start, self, onHttpRequestStart);
416417
try self.cdp.browser.notification.register(.http_request_complete, self, onHttpRequestComplete);
417418
}
418419

419420
pub fn networkDisable(self: *Self) void {
421+
self.cdp.browser.notification.unregister(.http_request_fail, self);
420422
self.cdp.browser.notification.unregister(.http_request_start, self);
421423
self.cdp.browser.notification.unregister(.http_request_complete, self);
422424
}
@@ -448,6 +450,12 @@ pub fn BrowserContext(comptime CDP_T: type) type {
448450
return @import("domains/network.zig").httpRequestStart(self.notification_arena, self, data);
449451
}
450452

453+
pub fn onHttpRequestFail(ctx: *anyopaque, data: *const Notification.RequestFail) !void {
454+
const self: *Self = @alignCast(@ptrCast(ctx));
455+
defer self.resetNotificationArena();
456+
return @import("domains/network.zig").httpRequestFail(self.notification_arena, self, data);
457+
}
458+
451459
pub fn onHttpRequestComplete(ctx: *anyopaque, data: *const Notification.RequestComplete) !void {
452460
const self: *Self = @alignCast(@ptrCast(ctx));
453461
defer self.resetNotificationArena();

src/cdp/domains/network.zig

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,24 @@ fn putAssumeCapacity(headers: *std.ArrayListUnmanaged(std.http.Header), extra: s
8484
return true;
8585
}
8686

87+
pub fn httpRequestFail(arena: Allocator, bc: anytype, request: *const Notification.RequestFail) !void {
88+
// Isn't possible to do a network request within a Browser (which our
89+
// notification is tied to), without a page.
90+
std.debug.assert(bc.session.page != null);
91+
92+
// all unreachable because we _have_ to have a page.
93+
const session_id = bc.session_id orelse unreachable;
94+
95+
// We're missing a bunch of fields, but, for now, this seems like enough
96+
try bc.cdp.sendEvent("Network.loadingFailed", .{
97+
.requestId = try std.fmt.allocPrint(arena, "REQ-{d}", .{request.id}),
98+
// Seems to be what chrome answers with. I assume it depends on the type of error?
99+
.type = "Ping",
100+
.errorText = request.err,
101+
.canceled = false,
102+
}, .{ .session_id = session_id });
103+
}
104+
87105
pub fn httpRequestStart(arena: Allocator, bc: anytype, request: *const Notification.RequestStart) !void {
88106
// Isn't possible to do a network request within a Browser (which our
89107
// notification is tied to), without a page.

src/http/client.zig

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -354,6 +354,7 @@ pub const Request = struct {
354354
// Because of things like redirects and error handling, it is possible for
355355
// the notification functions to be called multiple times, so we guard them
356356
// with these booleans
357+
_notified_fail: bool,
357358
_notified_start: bool,
358359
_notified_complete: bool,
359360

@@ -414,6 +415,7 @@ pub const Request = struct {
414415
._keepalive = false,
415416
._redirect_count = 0,
416417
._has_host_header = false,
418+
._notified_fail = false,
417419
._notified_start = false,
418420
._notified_complete = false,
419421
._connection_from_keepalive = false,
@@ -428,6 +430,7 @@ pub const Request = struct {
428430
}
429431

430432
pub fn abort(self: *Request) void {
433+
self.requestFailed("aborted");
431434
const aborter = self._aborter orelse {
432435
self.deinit();
433436
return;
@@ -555,6 +558,10 @@ pub const Request = struct {
555558
}
556559

557560
fn doSendSync(self: *Request, use_pool: bool) anyerror!Response {
561+
// https://github.com/ziglang/zig/issues/20369
562+
// errdefer |err| self.requestFailed(@errorName(err));
563+
errdefer self.requestFailed("network error");
564+
558565
if (use_pool) {
559566
if (self.findExistingConnection(true)) |connection| {
560567
self._connection = connection;
@@ -847,6 +854,19 @@ pub const Request = struct {
847854
});
848855
}
849856

857+
fn requestFailed(self: *Request, err: []const u8) void {
858+
const notification = self.notification orelse return;
859+
if (self._notified_fail) {
860+
return;
861+
}
862+
self._notified_fail = true;
863+
notification.dispatch(.http_request_fail, &.{
864+
.id = self.id,
865+
.err = err,
866+
.url = self.request_uri,
867+
});
868+
}
869+
850870
fn requestCompleted(self: *Request, response: ResponseHeader) void {
851871
const notification = self.notification orelse return;
852872
if (self._notified_complete) {
@@ -1290,6 +1310,8 @@ fn AsyncHandler(comptime H: type, comptime L: type) type {
12901310
self.handler.onHttpResponse(err) catch {};
12911311
// just to be safe
12921312
self.request._keepalive = false;
1313+
1314+
self.request.requestFailed(@errorName(err));
12931315
self.request.deinit();
12941316
}
12951317

src/notification.zig

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ pub const Notification = struct {
5959
page_created: List = .{},
6060
page_navigate: List = .{},
6161
page_navigated: List = .{},
62+
http_request_fail: List = .{},
6263
http_request_start: List = .{},
6364
http_request_complete: List = .{},
6465
notification_created: List = .{},
@@ -69,6 +70,7 @@ pub const Notification = struct {
6970
page_created: *page.Page,
7071
page_navigate: *const PageNavigate,
7172
page_navigated: *const PageNavigated,
73+
http_request_fail: *const RequestFail,
7274
http_request_start: *const RequestStart,
7375
http_request_complete: *const RequestComplete,
7476
notification_created: *Notification,
@@ -97,6 +99,12 @@ pub const Notification = struct {
9799
has_body: bool,
98100
};
99101

102+
pub const RequestFail = struct {
103+
id: usize,
104+
url: *const std.Uri,
105+
err: []const u8,
106+
};
107+
100108
pub const RequestComplete = struct {
101109
id: usize,
102110
url: *const std.Uri,

src/runtime/loop.zig

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,6 @@ pub const Loop = struct {
127127
}
128128
}
129129

130-
131130
// JS callbacks APIs
132131
// -----------------
133132

@@ -255,7 +254,6 @@ pub const Loop = struct {
255254
}
256255
}.onConnect;
257256

258-
259257
const callback = try self.event_callback_pool.create();
260258
errdefer self.event_callback_pool.destroy(callback);
261259
callback.* = .{ .loop = self, .ctx = ctx };

0 commit comments

Comments
 (0)