From 023caf9ce56093b6a82a8334154d3bbf89fe03c3 Mon Sep 17 00:00:00 2001 From: Ben Younes Date: Sat, 9 May 2026 17:36:11 +0200 Subject: [PATCH] fix(cdp): return descriptive error for Page.printToPDF instead of generic Unknown Page method (#53) (#112) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Playwright's `page.pdf()` issues a `Page.printToPDF` CDP request which Obscura was not handling, so the dispatcher fell through to the generic catch-all and clients saw: Page.pdf: Protocol error (Page.printToPDF): Unknown Page method: printToPDF This reads like an oversight rather than a deliberate limitation. Obscura intentionally has no layout engine — option (2) from the issue — so make the limitation explicit by handling the method and returning a clear error that names the method, says why it isn't supported, and points users at a working alternative (extract HTML via Runtime.evaluate, then render to PDF in their client). The behavior change is small but meaningful for DX: the JSON-RPC error code stays -32601 (the dispatcher's mapping for `Err(_)`), but the human-readable message becomes actionable instead of looking like a forgotten method. Adds a unit test that pins the regression: printToPDF must NOT fall through to the "Unknown Page method" catch-all and must mention both "not supported" and a workaround. Generated by Ora Studio Vibe coded by ousamabenyounes Co-authored-by: Ora Studio --- crates/obscura-cdp/src/domains/page.rs | 39 ++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/crates/obscura-cdp/src/domains/page.rs b/crates/obscura-cdp/src/domains/page.rs index 429b2bb..5208a66 100644 --- a/crates/obscura-cdp/src/domains/page.rs +++ b/crates/obscura-cdp/src/domains/page.rs @@ -273,6 +273,20 @@ pub async fn handle( }] })) } + "printToPDF" => { + // Obscura has no layout/rendering engine, so PDF generation is + // intentionally not implemented. Returning a distinct, descriptive + // error (rather than the generic "Unknown Page method" fallback) + // tells Playwright/Puppeteer/headless_chrome clients exactly why + // the call failed and what to do instead. + Err( + "Page.printToPDF is not supported by Obscura: no layout engine. \ + Use Runtime.evaluate (e.g. page.evaluate) to extract the rendered \ + HTML, then render to PDF in your client (wkhtmltopdf, weasyprint, \ + a separate headless Chromium pipeline, etc.)." + .to_string(), + ) + } _ => Err(format!("Unknown Page method: {}", method)), } } @@ -333,4 +347,29 @@ mod tests { .expect_err("unknown methods must surface as errors"); assert!(err.contains("Unknown Page method")); } + + #[tokio::test] + async fn print_to_pdf_returns_descriptive_unsupported_error() { + // Regression for #53: Page.printToPDF must be handled explicitly so + // Playwright clients receive a descriptive error rather than the + // generic "Unknown Page method" fallback. + let mut ctx = CdpContext::new(); + let err = handle("printToPDF", &json!({}), &mut ctx, &None) + .await + .expect_err("printToPDF must error until a real renderer exists"); + assert!( + !err.contains("Unknown Page method"), + "printToPDF must NOT fall through to the catch-all: {err}" + ); + assert!( + err.contains("not supported by Obscura"), + "error must clearly state PDF is unsupported: {err}" + ); + // Direct user to a workaround so the message is actionable. + assert!( + err.to_lowercase().contains("evaluate") + || err.to_lowercase().contains("html"), + "error must point to a workaround: {err}" + ); + } }