mirror of
https://github.com/electron/electron.git
synced 2026-05-02 03:00:22 -04:00
fix: reset printToPDF queue after a rejection (#51222)
fix: reset printToPDF queue after a rejection The module-scoped `pendingPromise` in `webContents.printToPDF` was chained with `.then(onFulfilled)` and never cleared. Once a call rejected (e.g. an out-of-range `pageRanges` like `"999"`), subsequent calls chained onto the rejected promise and short-circuited without ever invoking `_printToPDF` — so every following call re-surfaced the original error. Replace the shared variable with a per-`WebContents` `WeakMap` queue that swallows prior rejections before chaining and clears its entry once the tail drains. Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com> Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
This commit is contained in:
@@ -212,7 +212,7 @@ function parsePageSize (pageSize: string | ElectronInternal.PageSize) {
|
||||
|
||||
// Translate the options of printToPDF.
|
||||
|
||||
let pendingPromise: Promise<any> | undefined;
|
||||
const printToPDFQueues = new WeakMap<Electron.WebContents, Promise<unknown>>();
|
||||
WebContents.prototype.printToPDF = async function (options) {
|
||||
const margins = checkType(options.margins ?? {}, 'object', 'margins');
|
||||
const pageSize = parsePageSize(options.pageSize ?? 'letter');
|
||||
@@ -244,16 +244,19 @@ WebContents.prototype.printToPDF = async function (options) {
|
||||
...pageSize
|
||||
};
|
||||
|
||||
if (this._printToPDF) {
|
||||
if (pendingPromise) {
|
||||
pendingPromise = pendingPromise.then(() => this._printToPDF(printSettings));
|
||||
} else {
|
||||
pendingPromise = this._printToPDF(printSettings);
|
||||
}
|
||||
return pendingPromise;
|
||||
} else {
|
||||
if (!this._printToPDF) {
|
||||
throw new Error('Printing feature is disabled');
|
||||
}
|
||||
|
||||
const prev = printToPDFQueues.get(this) ?? Promise.resolve();
|
||||
const next = prev.catch(() => {}).then(() => this._printToPDF(printSettings));
|
||||
printToPDFQueues.set(this, next);
|
||||
next
|
||||
.finally(() => {
|
||||
if (printToPDFQueues.get(this) === next) printToPDFQueues.delete(this);
|
||||
})
|
||||
.catch(() => {});
|
||||
return next;
|
||||
};
|
||||
|
||||
// TODO(codebytere): deduplicate argument sanitization by moving rest of
|
||||
|
||||
@@ -3080,6 +3080,16 @@ describe('webContents module', () => {
|
||||
expect(pdfInfo.numPages).to.equal(3);
|
||||
});
|
||||
|
||||
it('recovers after a prior call fails with an invalid page range', async () => {
|
||||
await w.loadURL('data:text/html,<h1>Hello, World!</h1>');
|
||||
|
||||
await expect(w.webContents.printToPDF({ pageRanges: '999' })).to.eventually.be.rejected();
|
||||
|
||||
const data = await w.webContents.printToPDF({});
|
||||
const pdfInfo = await readPDF(data);
|
||||
expect(pdfInfo.numPages).to.equal(1);
|
||||
});
|
||||
|
||||
it('does not tag PDFs by default', async () => {
|
||||
await w.loadFile(path.join(__dirname, 'fixtures', 'api', 'print-to-pdf-small.html'));
|
||||
|
||||
|
||||
Reference in New Issue
Block a user