Skip to content

Await the start_url navigation and surface its failures - #338

Closed
yummybomb wants to merge 1 commit into
mainfrom
hypeship/await-start-url-navigation
Closed

Await the start_url navigation and surface its failures#338
yummybomb wants to merge 1 commit into
mainfrom
hypeship/await-start-url-navigation

Conversation

@yummybomb

Copy link
Copy Markdown

Summary

/configure's start_url step gave the navigation a 3s budget and treated
anything else as best-effort. Two failure modes fell out of that, both of which
end with the session being handed over on the page it was already showing while
the endpoint reports success:

  1. The budget was too short to reach commit. Page.navigate only resolves
    once the navigation commits, so the budget has to cover the origin's DNS,
    connect and first byte. Against an origin slower than 3s the context expired,
    the handler logged a warning and returned 200, and the navigation committed a
    few seconds later — after the caller already had the browser.
  2. A navigation that could not load read as success. Chrome answers
    Page.navigate with an errorText and commits an error page when the URL is
    unreachable. DispatchStartURL discarded the result, so an unreachable
    start_url returned no error at all.

What changed

  • startURLDispatchTimeout (3s) becomes startURLNavigateTimeout (15s). Commit
    semantics mean this only has to cover time to first byte, not subresource
    loading, so it does not slow down heavy pages.
  • cdpclient.DispatchStartURL returns Chrome's navigation errorText alongside
    its error, letting callers distinguish a committed navigation from a committed
    error page. DispatchStartURLAndWait ignores it deliberately — its polling
    loop already re-navigates through chrome-error:// — and the wrapper's
    about:blank reset is unchanged in behavior.
  • Both failure modes log start_url dispatch failed with the elapsed time. The
    message is unchanged so existing log queries keep matching.
  • A failed navigation still returns 200. Returning non-2xx would make the caller
    treat the instance as tainted and discard an otherwise healthy browser over a
    start_url the caller may not control.
  • The OpenAPI description now states that the navigation is awaited to commit and
    that a failure is logged and still returns 200. Descriptions do not reach
    generated code, so lib/oapi/oapi.go is unchanged; lib/events/category_gen.go
    was regenerated and is unchanged.

Verification

Local reproduction driving Chromium 151 under Xvfb with the headful image's flag
set, calling this package's DispatchStartURL behind a replica of
startChromiumAndWait's readiness gate:

case before after
origin 6s to first byte errors at 3.00s (Page.navigate: read: failed to get reader: context deadline exceeded), handover still renders the previous page, navigation commits at ~6.2s returns ok at 6.06s, after commit
unreachable start_url returns ok, no error reported, browser on an error page reports net::ERR_CONNECTION_REFUSED
document commits, subresource stalls 20s ok at 67ms ok at 67ms (unchanged — confirms commit, not load, semantics)

Also measured that restored tab targets all exist before the readiness gate
returns (checked up to 40 tabs), so the single Target.getTargets snapshot is
not racing target creation.

New unit tests cover a committed navigation, a reported errorText, and a
navigation that does not commit within the budget. go vet and the full unit
suite pass (22 packages); the e2e suite needs Docker images and was not run.

Notes for review

  • 15s is a judgement call: long enough for slow-to-commit origins, bounded so a
    hung origin cannot stall a configure indefinitely. It sits well inside the
    calling activity's timeout.
  • A caller-visible signal for a failed navigation would need a response schema
    field, which requires the npm down-converter for codegen. Left out here, so the
    failure remains observable only in instance logs.
  • The deployed images build from the private fork, so this needs to be synced
    there before it ships.

Page.navigate only resolves once the navigation commits, so the 3s budget
on /configure's start_url step expired against origins that were slow to
answer. The handler then logged a warning, returned 200, and handed the
session over still rendering the pre-navigation page while the navigation
committed seconds later.

Chrome also reports an unreachable URL by returning an errorText from
Page.navigate and committing an error page. DispatchStartURL discarded the
result, so that read as a successful navigation.

Raise the navigate budget to 15s, which covers a slow origin's DNS,
connect and first byte; commit semantics mean it does not have to cover
subresource loading. Return Chrome's errorText from DispatchStartURL so
callers can tell a committed navigation from a committed error page, and
log both failure modes with the elapsed time. A navigation that still
fails keeps returning 200 rather than discarding an otherwise healthy
browser over a start_url the caller may not control.
@yummybomb yummybomb closed this Aug 17, 2026
@yummybomb
yummybomb deleted the hypeship/await-start-url-navigation branch August 17, 2026 20:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant