'chromedp - Go - Show invalid printer settings error (-32000) - When setting WithMarginTop

I'm playing around with chromedp and been trying to replicate the functionality in puppeteer node.js but in golang.

I'm finding that the same JSON payload to chromium is causing an error when using chromedp


package main

import (
    "context"
    "io/ioutil"
    "log"

    "github.com/chromedp/cdproto/page"
    "github.com/chromedp/chromedp"
)

func main() {
    // create context
    ctx, cancel := chromedp.NewContext(context.Background())
    defer cancel()

    // capture pdf
    var buf []byte
    if err := chromedp.Run(ctx, printToPDF(`<html><body><h1>Yeeeew!</h1></body></html>`, &buf)); err != nil {
        log.Fatal(err)
    }

    if err := ioutil.WriteFile("sample.pdf", buf, 0644); err != nil {
        log.Fatal(err)
    }
}

// https://github.com/puppeteer/puppeteer/blob/4d9dc8c0e613f22d4cdf237e8bd0b0da3c588edb/src/common/PDFOptions.ts#L74
// https://github.com/puppeteer/puppeteer/blob/4d9dc8c0e613f22d4cdf237e8bd0b0da3c588edb/src/common/Page.ts#L3366
//https://github.com/chromedp/chromedp/issues/836
func printToPDF(html string, res *[]byte) chromedp.Tasks {
    return chromedp.Tasks{
        chromedp.Navigate("about:blank"),
        chromedp.ActionFunc(func(ctx context.Context) error {
            frameTree, err := page.GetFrameTree().Do(ctx)
            if err != nil {
                return err
            }

            return page.SetDocumentContent(frameTree.Frame.ID, html).Do(ctx)
        }),
        chromedp.ActionFunc(func(ctx context.Context) error {
            buf, _, err := page.PrintToPDF().
                // WithPrintBackground(false).
                WithMarginTop(20.0).
                // WithMarginLeft(20).
                // WithMarginBottom(20.0).
                // WithMarginRight(20).
                Do(ctx)
            if err != nil {
                return err
            }
            *res = buf
            return nil
        }),
    }
}

I've vendored the modules and edited cdproto/page/page.go to print out the JSON being sent to chromium

{"marginTop":20,"marginBottom":0,"marginLeft":0,"marginRight":0,"transferMode":"ReturnAsStream"}

I've also done this in node.js and logged out the json to compare


node index.js 
PDF command: 'Page.printToPDF' {
  transferMode: 'ReturnAsStream',
  marginTop: 20,
  marginBottom: 20,
  marginLeft: 0,
  marginRight: 0
}

I'm not sure why I'm getting this error? Any ideas?



Solution 1:[1]

TL;DR

The margin value is too big. I think you meant to pass 20.0/96 inches:

-        WithMarginTop(20.0).
+        WithMarginTop(20.0/96).

Explanation

The error message returned from chromium is misleading. I guess here is what happened: the provided margin settings is invalid, and since chromium is running in headless mode, it can not show the error dialog. The error message can be interpreted as "I can not show a dialog to alert the user that the provided printer settings are invalid".

"marginTop":20 in the raw CDP message means 20 inches on the top, which is too big for an A4 page (A4: 8.27in x 11.7in). Please note that a number in puppeteer is treated as pixels and will be converted to inches before sending to chromium (see https://github.com/puppeteer/puppeteer/blob/4d9dc8c0e613f22d4cdf237e8bd0b0da3c588edb/src/common/Page.ts#L3366-L3402). So the fix is obvious.

BTW, there are easy ways to see the raw CDP messages:

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Zeke Lu