fix(client): handle missing document in preview frame (#44833)

This commit is contained in:
Oliver Eyton-Williams
2022-01-20 14:22:25 +01:00
committed by GitHub
parent 5aaf8677d4
commit f88473f994

View File

@ -9,6 +9,8 @@ const testId = 'fcc-test-frame';
// the project preview frame demos the finished project // the project preview frame demos the finished project
export const projectPreviewId = 'fcc-project-preview-frame'; export const projectPreviewId = 'fcc-project-preview-frame';
const DOCUMENT_NOT_FOUND_ERROR = 'document not found';
// base tag here will force relative links // base tag here will force relative links
// within iframe to point to '' instead of // within iframe to point to '' instead of
// append to the current challenge url // append to the current challenge url
@ -103,7 +105,8 @@ const buildProxyConsole = proxyLogger => ctx => {
}; };
const initTestFrame = frameReady => ctx => { const initTestFrame = frameReady => ctx => {
waitForFrame(ctx).then(async () => { waitForFrame(ctx)
.then(async () => {
const { sources, loadEnzyme } = ctx; const { sources, loadEnzyme } = ctx;
// default for classic challenges // default for classic challenges
// should not be used for modern // should not be used for modern
@ -115,12 +118,14 @@ const initTestFrame = frameReady => ctx => {
const getUserInput = fileName => toString(sources[fileName]); const getUserInput = fileName => toString(sources[fileName]);
await ctx.document.__initTestFrame({ code, getUserInput, loadEnzyme }); await ctx.document.__initTestFrame({ code, getUserInput, loadEnzyme });
frameReady(); frameReady();
}); })
.catch(handleDocumentNotFound);
return ctx; return ctx;
}; };
const initMainFrame = (_, proxyLogger) => ctx => { const initMainFrame = (_, proxyLogger) => ctx => {
waitForFrame(ctx).then(() => { waitForFrame(ctx)
.then(() => {
// Overwriting the onerror added by createHeader to catch any errors thrown // Overwriting the onerror added by createHeader to catch any errors thrown
// after the frame is ready. It has to be overwritten, as proxyLogger cannot // after the frame is ready. It has to be overwritten, as proxyLogger cannot
// be added as part of createHeader. // be added as part of createHeader.
@ -136,15 +141,24 @@ const initMainFrame = (_, proxyLogger) => ctx => {
// an error from a cross origin script just appears as 'Script error.' // an error from a cross origin script just appears as 'Script error.'
return false; return false;
}; };
}); })
.catch(handleDocumentNotFound);
return ctx; return ctx;
}; };
function handleDocumentNotFound(err) {
if (err !== DOCUMENT_NOT_FOUND_ERROR) {
console.log(err);
}
}
const initPreviewFrame = () => ctx => ctx; const initPreviewFrame = () => ctx => ctx;
const waitForFrame = ctx => { const waitForFrame = ctx => {
return new Promise(resolve => { return new Promise((resolve, reject) => {
if (ctx.document.readyState === 'loading') { if (!ctx.document) {
reject(DOCUMENT_NOT_FOUND_ERROR);
} else if (ctx.document.readyState === 'loading') {
ctx.document.addEventListener('DOMContentLoaded', resolve); ctx.document.addEventListener('DOMContentLoaded', resolve);
} else { } else {
resolve(); resolve();
@ -153,10 +167,13 @@ const waitForFrame = ctx => {
}; };
function writeToFrame(content, frame) { function writeToFrame(content, frame) {
// it's possible, if the preview is rapidly opened and closed, for the frame
// to be null at this point.
if (frame) {
frame.open(); frame.open();
frame.write(content); frame.write(content);
frame.close(); frame.close();
return frame; }
} }
const writeContentToFrame = ctx => { const writeContentToFrame = ctx => {