Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: don't reject loadURL() promise from did-fail-load - use did-finish-load instead #40661

Merged
merged 4 commits into from Dec 12, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
22 changes: 16 additions & 6 deletions lib/browser/api/web-contents.ts
Expand Up @@ -333,24 +333,31 @@ WebContents.prototype.loadFile = function (filePath, options = {}) {
}));
};

type LoadError = { errorCode: number, errorDescription: string, url: string };

WebContents.prototype.loadURL = function (url, options) {
const p = new Promise<void>((resolve, reject) => {
const resolveAndCleanup = () => {
removeListeners();
resolve();
};
const rejectAndCleanup = (errorCode: number, errorDescription: string, url: string) => {
let error: LoadError | undefined;
const rejectAndCleanup = ({ errorCode, errorDescription, url }: LoadError) => {
const err = new Error(`${errorDescription} (${errorCode}) loading '${typeof url === 'string' ? url.substr(0, 2048) : url}'`);
Object.assign(err, { errno: errorCode, code: errorDescription, url });
removeListeners();
reject(err);
};
const finishListener = () => {
resolveAndCleanup();
if (error) {
rejectAndCleanup(error);
} else {
resolveAndCleanup();
}
};
const failListener = (event: Electron.Event, errorCode: number, errorDescription: string, validatedURL: string, isMainFrame: boolean) => {
if (isMainFrame) {
rejectAndCleanup(errorCode, errorDescription, validatedURL);
if (!error && isMainFrame) {
error = { errorCode, errorDescription, url: validatedURL };
}
};

Expand All @@ -368,7 +375,7 @@ WebContents.prototype.loadURL = function (url, options) {
// considered navigation events but are triggered with isSameDocument.
// We can ignore these to allow virtual routing on page load as long
// as the routing does not leave the document
return rejectAndCleanup(-3, 'ERR_ABORTED', url);
return rejectAndCleanup({ errorCode: -3, errorDescription: 'ERR_ABORTED', url });
}
browserInitiatedInPageNavigation = navigationStarted && isSameDocument;
navigationStarted = true;
Expand All @@ -383,7 +390,10 @@ WebContents.prototype.loadURL = function (url, options) {
// TODO(jeremy): enumerate all the cases in which this can happen. If
// the only one is with a bad scheme, perhaps ERR_INVALID_ARGUMENT
// would be more appropriate.
rejectAndCleanup(-2, 'ERR_FAILED', url);
if (!error) {
error = { errorCode: -2, errorDescription: 'ERR_FAILED', url: url };
}
finishListener();
};
const finishListenerWhenUserInitiatedNavigation = () => {
if (!browserInitiatedInPageNavigation) {
Expand Down
5 changes: 5 additions & 0 deletions spec/api-web-contents-spec.ts
Expand Up @@ -514,6 +514,11 @@ describe('webContents module', () => {
.and.have.property('errno', -355); // ERR_INCOMPLETE_CHUNKED_ENCODING
s.close();
});

it('subsequent load failures reject each time', async () => {
await expect(w.loadURL('file:non-existent')).to.eventually.be.rejected();
await expect(w.loadURL('file:non-existent')).to.eventually.be.rejected();
});
});

describe('getFocusedWebContents() API', () => {
Expand Down