diff --git a/server/hydrogen-render/1-render-hydrogen-to-string.js b/server/hydrogen-render/1-render-hydrogen-to-string.js index 7301749..dbdf841 100644 --- a/server/hydrogen-render/1-render-hydrogen-to-string.js +++ b/server/hydrogen-render/1-render-hydrogen-to-string.js @@ -6,6 +6,7 @@ const fork = require('child_process').fork; +const assert = require('assert'); const RethrownError = require('../lib/rethrown-error'); // The render should be fast. If it's taking more than 5 seconds, something has @@ -60,12 +61,16 @@ async function renderHydrogenToString(options) { } else { let extraErrorsMessage = ''; if (childErrors.length > 1) { - extraErrorsMessage = ` (somehow we saw ${childErrors.length} errors but we really always expect 1 error)`; + extraErrorsMessage = ` (somehow we saw ${ + childErrors.length + } errors but we really always expect 1 error)\n${childErrors + .map((childError, index) => ` ${index}. ${childError.message} ${childError.stack}`) + .join('\n')}`; } const error = new RethrownError( `Child process failed with exit code ${exitCode}${extraErrorsMessage}`, - childErrors[0] + childErrors[0] || new Error('No child errors') ); reject(error); } @@ -84,6 +89,11 @@ async function renderHydrogenToString(options) { }); }); + assert( + data, + `No HTML sent from child process to render Hydrogen. Any child errors? (${childErrors.length})` + ); + return data; } catch (err) { throw new RethrownError( diff --git a/server/hydrogen-render/2-render-hydrogen-to-string-fork-script.js b/server/hydrogen-render/2-render-hydrogen-to-string-fork-script.js index 1ade0b3..5158019 100644 --- a/server/hydrogen-render/2-render-hydrogen-to-string-fork-script.js +++ b/server/hydrogen-render/2-render-hydrogen-to-string-fork-script.js @@ -4,6 +4,8 @@ // get the data and exit the process cleanly. We don't want Hydrogen to keep // running after we get our initial rendered HTML. +const assert = require('assert'); + const _renderHydrogenToStringUnsafe = require('./3-render-hydrogen-to-string-unsafe'); // Only kick everything off once we receive the options. We pass in the options @@ -13,12 +15,31 @@ process.on('message', async (options) => { try { const resultantHtml = await _renderHydrogenToStringUnsafe(options); - // Send back the data we need - process.send({ - data: resultantHtml, + assert(resultantHtml, `No HTML returned from _renderHydrogenToStringUnsafe.`); + + // Send back the data we need to the parent. + await new Promise((resolve, reject) => { + process.send( + { + data: resultantHtml, + }, + (err) => { + if (err) { + return reject(err); + } + + // Exit once we know the data was sent out. We can't gurantee the + // message was received but this should work pretty well. + // + // Related: + // - https://stackoverflow.com/questions/34627546/process-send-is-sync-async-on-nix-windows + // - https://github.com/nodejs/node/commit/56d9584a0ead78874ca9d4de2e55b41c4056e502 + // - https://github.com/nodejs/node/issues/6767 + process.exit(0); + resolve(); + } + ); }); - // End the process gracefully. We got all the data we need. - process.exit(0); } catch (err) { // Serialize the error and send it back up to the parent process so we can // interact with it and know what happened when the process exits. diff --git a/server/hydrogen-render/3-render-hydrogen-to-string-unsafe.js b/server/hydrogen-render/3-render-hydrogen-to-string-unsafe.js index fc7adf7..fc95e62 100644 --- a/server/hydrogen-render/3-render-hydrogen-to-string-unsafe.js +++ b/server/hydrogen-render/3-render-hydrogen-to-string-unsafe.js @@ -94,6 +94,7 @@ async function _renderHydrogenToStringUnsafe({ fromTimestamp, roomData, events, await vmResult; const documentString = dom.document.body.toString(); + assert(documentString, 'Document body should not be empty after we rendered Hydrogen'); return documentString; }