RelaxedJS/ReLaXed

masterToPDF fails on second run

jwmann opened this issue · 1 comments

I'm using the example from the README, you can see it here:
https://github.com/RelaxedJS/ReLaXed#using-it-as-a-node-module

This is there error in question:

(node:5151) UnhandledPromiseRejectionWarning: TypeError: Cannot convert undefined or null to object
    at Function.assign (<anonymous>)
    at exports.masterToPDF (/Users/jwm/work/app/node_modules/relaxedjs/src/masterToPDF.js:24:29)
    at HTML2PDF.pdf (/Users/jwm/work/app/src/actions/html2pdf.js:49:11)
    at /Users/jwm/work/app/src/router.js:30:28
    at processTicksAndRejections (internal/process/task_queues.js:93:5)
(node:5151) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 2)
(node:5151) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

This references this line in masterToPDF:
https://github.com/RelaxedJS/ReLaXed/blob/master/src/masterToPDF.js#L24

This made me curious what the relaxedGlobals actually are.

This is from the first run:

{
  relaxedGlobals: {
    busy: false,
    config: {},
    configPlugins: [],
    pluginHooks: {
      watchers: [Array],
      pugHeaders: [],
      pugFilters: [Array],
      headElements: [Array],
      htmlModifiers: [],
      pageModifiers: [],
      page2ndModifiers: [],
      postPDF: []
    },
    watchedExtensions: [
      '.pug',        '.md',
      '.html',       '.css',
      '.scss',       '.svg',
      '.png',        '.jpeg',
      '.jpg',        '.table.csv',
      '.htable.csv', '.htable.md.csv',
      '.chart.js',   '.vegalite.json',
      '.flowchart',  '.flowchart.json',
      '.mermaid'
    ],
    puppeteerPage: Page {
      _events: [Object: null prototype] {},
      _eventsCount: 0,
      _maxListeners: undefined,
      _closed: false,
      _client: [CDPSession],
      _target: [Target],
      _keyboard: [Keyboard],
      _mouse: [Mouse],
      _timeoutSettings: [TimeoutSettings],
      _touchscreen: [Touchscreen],
      _accessibility: [Accessibility],
      _frameManager: [FrameManager],
      _emulationManager: [EmulationManager],
      _tracing: [Tracing],
      _pageBindings: Map {},
      _coverage: [Coverage],
      _javascriptEnabled: true,
      _viewport: [Object],
      _screenshotTaskQueue: [TaskQueue],
      _workers: Map {},
      _fileChooserInterceptionIsDisabled: false,
      _fileChooserInterceptors: Set {}
    }
  }
}

pugFilters looks like this:

{
  pugFilters: [
    { instance: { scss: [Function: ScssPugFilter] }, origin: undefined },
    { instance: { markdown: [Function: MarkdownPugFilter] }, origin: undefined }
  ]
}

This is from the second run:

{
  relaxedGlobals: {
    busy: false,
    config: {},
    configPlugins: [],
    pluginHooks: {
      watchers: [],
      pugHeaders: [],
      pugFilters: [],
      headElements: [],
      htmlModifiers: [],
      pageModifiers: [],
      page2ndModifiers: [],
      postPDF: []
    },
    watchedExtensions: [
      '.pug',  '.md',
      '.html', '.css',
      '.scss', '.svg',
      '.png',  '.jpeg',
      '.jpg' 
    ],
    puppeteerPage: Page {
      _events: [Object: null prototype] {},
      _eventsCount: 0,
      _maxListeners: undefined,
      _closed: false,
      _client: [CDPSession],
      _target: [Target],
      _keyboard: [Keyboard],
      _mouse: [Mouse],
      _timeoutSettings: [TimeoutSettings],
      _touchscreen: [Touchscreen],
      _accessibility: [Accessibility],
      _frameManager: [FrameManager],
      _emulationManager: [EmulationManager],
      _tracing: [Tracing],
      _pageBindings: Map {},
      _coverage: [Coverage],
      _javascriptEnabled: true,
      _viewport: [Object],
      _screenshotTaskQueue: [TaskQueue],
      _workers: Map {},
      _fileChooserInterceptionIsDisabled: false,
      _fileChooserInterceptors: Set {}
    }
  }
}

It seems that on the second run, we're missing a whole bunch of watchedExtensions as well as pugFilters, headElements and watchers

I'm not doing anything different on the second run.

I've found the issue.
In the example it tells you to run the _initilizePlugins() function in order to build the default plugins for relaxed to work. However, when you try to run it again, it will try to initialize already initialized plugins thus destroying all the default plugins.

I solved this by putting a boolean flag in the class and then setting that flag when the plugins runs and then checking whether it has or not before running.

I will probably create a PR to fix this.