esdoc2 / esdoc2-plugins

MIT License
6 stars 5 forks source link

Multiple execution errors generating documentation #1

Closed rgsilva closed 6 years ago

rgsilva commented 6 years ago

Hi!

So, as discussed in https://github.com/esdoc2/esdoc2/issues/2, I managed to get esdoc2 working by cloning and building it manually (which is actually better for our workflow here). However, I ran into some issues generating documentation for some test folders.

First thing I did was to modify esdoc2 to show me where unhandled promise rejections crashed, following the instrunctions from StackOverflow: https://stackoverflow.com/questions/43834559/how-to-find-which-promises-is-unhandled-in-nodejs-unhandledpromiserejectionwarni.

I've create a folder called src and created the testfile.js inside of it:

/**
 * Model service yey.
 */
class ModelService {
  constructor() {}

  /**
   * A random method.
   */
  foo() {}
}

The esdoc2 configuration file is this:

{
  "source": "./src",
  "destination": "./docs",
  "plugins": [
    {
      "name": "esdoc2-standard-plugin",
      "option": {
        "lint": {"enable": false}
      }
    }
  ]
}

Trying to generate the documentation for that small file resulted in this warning:

(node:20455) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): Error: ENOENT: no such file or directory, open './README.md'

By adding the missing (empty) README.md, I got the following:

ricardo@desenv4 ~/tmp2/test $ ~/tmp2/esdoc2/out/src/ESDocCLI.js -c esdoc2.json 
ESDoc2 info using node@v8.9.2
ESDoc2 info using esdoc2@2.0.0
ESDoc2 info config esdoc2.json
ESDoc2 info parse /home/ricardo/tmp2/test/src/.external-ecmascript.js
ESDoc2 info parse /home/ricardo/tmp2/test/src/testfile.js
Unhandled Rejection at: Promise Promise {
  <rejected> TypeError: Cannot read property 'params' of undefined
    at Plugin._inferenceParam (/home/ricardo/tmp2/esdoc2/node_modules/esdoc2-type-inference-plugin/src/Plugin.js:120:25)
    at Plugin._inferenceMethod (/home/ricardo/tmp2/esdoc2/node_modules/esdoc2-type-inference-plugin/src/Plugin.js:30:42)
    at Plugin._exec (/home/ricardo/tmp2/esdoc2/node_modules/esdoc2-type-inference-plugin/src/Plugin.js:17:10)
    at Plugin.onHandleDocs (/home/ricardo/tmp2/esdoc2/node_modules/esdoc2-type-inference-plugin/src/Plugin.js:11:10)
    at Plugin._execHandler (/home/ricardo/tmp2/esdoc2/out/src/Plugin/Plugin.js:77:30)
    at Plugin.onHandleDocs (/home/ricardo/tmp2/esdoc2/out/src/Plugin/Plugin.js:190:12)
    at /home/ricardo/tmp2/esdoc2/out/src/ESDoc.js:252:36
    at new Promise (<anonymous>)
    at Function.generate (/home/ricardo/tmp2/esdoc2/out/src/ESDoc.js:91:14)
    at ESDocCLI.exec (/home/ricardo/tmp2/esdoc2/out/src/ESDocCLI.js:94:25) } reason: TypeError: Cannot read property 'params' of undefined
    at Plugin._inferenceParam (/home/ricardo/tmp2/esdoc2/node_modules/esdoc2-type-inference-plugin/src/Plugin.js:120:25)
    at Plugin._inferenceMethod (/home/ricardo/tmp2/esdoc2/node_modules/esdoc2-type-inference-plugin/src/Plugin.js:30:42)
    at Plugin._exec (/home/ricardo/tmp2/esdoc2/node_modules/esdoc2-type-inference-plugin/src/Plugin.js:17:10)
    at Plugin.onHandleDocs (/home/ricardo/tmp2/esdoc2/node_modules/esdoc2-type-inference-plugin/src/Plugin.js:11:10)
    at Plugin._execHandler (/home/ricardo/tmp2/esdoc2/out/src/Plugin/Plugin.js:77:30)
    at Plugin.onHandleDocs (/home/ricardo/tmp2/esdoc2/out/src/Plugin/Plugin.js:190:12)
    at /home/ricardo/tmp2/esdoc2/out/src/ESDoc.js:252:36
    at new Promise (<anonymous>)
    at Function.generate (/home/ricardo/tmp2/esdoc2/out/src/ESDoc.js:91:14)
    at ESDocCLI.exec (/home/ricardo/tmp2/esdoc2/out/src/ESDocCLI.js:94:25)
ESDoc2 info esdoc2 finished generating files
ESDoc2 info write /home/ricardo/tmp2/test/docs/coverage.json
ESDoc2 info write /home/ricardo/tmp2/test/docs/badge.svg
resolve: extends chain
resolve: necessary
resolve: ignore
resolve: link
resolve: markdown in description
resolve: test relation

TypeError: Cannot read property 'find' of undefined
    at IdentifiersDocBuilder._buildLayoutDoc (/home/ricardo/tmp2/esdoc2/node_modules/esdoc2-publish-html-plugin/out/src/Builder/DocBuilder.js:184:34)
    at IdentifiersDocBuilder.exec (/home/ricardo/tmp2/esdoc2/node_modules/esdoc2-publish-html-plugin/out/src/Builder/IdentifiersDocBuilder.js:28:22)
    at Plugin._exec (/home/ricardo/tmp2/esdoc2/node_modules/esdoc2-publish-html-plugin/out/src/Plugin.js:91:69)
    at Plugin.onPublish (/home/ricardo/tmp2/esdoc2/node_modules/esdoc2-publish-html-plugin/out/src/Plugin.js:71:10)
    at Plugin._execHandler (/home/ricardo/tmp2/esdoc2/out/src/Plugin/Plugin.js:77:30)
    at Plugin.onPublish (/home/ricardo/tmp2/esdoc2/out/src/Plugin/Plugin.js:212:12)
    at Function._publish (/home/ricardo/tmp2/esdoc2/out/src/ESDoc.js:567:26)
    at Transform.onWriteFinish (/home/ricardo/tmp2/esdoc2/out/src/ESDoc.js:129:17)
    at emitNone (events.js:106:13)
    at Transform.emit (events.js:208:7)

There are 2 issues here. The first one is a promise rejection because of an exception, and the second one is a find call which is crashing esdoc2. Taking care of the second one first, I saw that DocBuilder gets its tags through the constructor. Such instance is created at the plugin itself, and by checking the source, it seems that the _exec call (https://github.com/esdoc2/esdoc2-plugins/blob/master/packages/esdoc2-publish-html-plugin/src/Plugin.js#L27) is calling with this._docs as undefined. By adding a console.log to the onHandleDocs method of such class, I got pretty much nothing: a call to it was never made. That seems to be the reason why it won't work. A hack was to change the call as this:

this._exec(this._docs, ev.data.writeFile, ev.data.copyDir, ev.data.readFile);

That fixed the second issue and we at least get some documentation output at the end. However, the first issue (params of undefined) is still present. This is happing because at https://github.com/esdoc2/esdoc2-plugins/blob/master/packages/esdoc2-type-inference-plugin/src/Plugin.js#L120, node is actually undefined. Taking a look back at who is calling it, it seems it happens because the following call is returning undefined in some cases:

const node = ASTNodeContainer.getNode(doc.__docId__);

If I add a condition to continue the loop in case the node is undefined (if (!node) continue;) to all parts of the code that call getNode, the documentation is finally generated. Plus, after doing that, onHandleDocs is finally called with data:

ricardo@desenv4 ~/tmp2/test $ ~/tmp2/esdoc2/out/src/ESDocCLI.js -c esdoc2.json 
ESDoc2 info using node@v8.9.2
ESDoc2 info using esdoc2@2.0.0
ESDoc2 info config esdoc2.json
ESDoc2 info parse /home/ricardo/tmp2/test/src/.external-ecmascript.js
ESDoc2 info parse /home/ricardo/tmp2/test/src/testfile.js

*** HACK: onHandleDocs called: [ { __docId__: 1, (.... ) } ]

ESDoc2 info esdoc2 finished generating files
ESDoc2 info write /home/ricardo/tmp2/test/docs/coverage.json
ESDoc2 info write /home/ricardo/tmp2/test/docs/badge.svg

*** HACK: onPublish called

resolve: extends chain
resolve: necessary
resolve: ignore
resolve: link
resolve: markdown in description
resolve: test relation
ESDoc2 info write /home/ricardo/tmp2/test/docs/identifiers.html
ESDoc2 info write /home/ricardo/tmp2/test/docs/index.html
ESDoc2 info write /home/ricardo/tmp2/test/docs/file/src/testfile.js.html
ESDoc2 info copy /home/ricardo/tmp2/test/docs/css
ESDoc2 info copy /home/ricardo/tmp2/test/docs/script
ESDoc2 info copy /home/ricardo/tmp2/test/docs/image
ESDoc2 info write /home/ricardo/tmp2/test/docs/script/search_index.js
ESDoc2 info write /home/ricardo/tmp2/test/docs/source.html

So! Can you tell me if I'm missing something somewhere, or if this is a proper solution (in such case I'll do a PR for you to review)? All I did was a few hacks to get it to carry on without errors, but I don't know the effects of it to the process itself. :)

Thanks! Cheers, Ricardo

PS: fun fact, esdoc2 takes over 10 minutes to run at our current project. I might have to disable some stuff we don't need/use right now :-)

MattMcFarland commented 6 years ago

Hi Ricardo, great job digging into this!

I'm perfectly fine with implementing graceful fallback for now. Since I'm not very familiar with the plugin code I can't say it is the proper solution, but I'd rather have it fixed now and find the proper solution later. Feel free to send a PR, and perhaps add a todo or issue to investigate it further when we have the chance!

Thanks! Matt

rgsilva commented 6 years ago

I'll close this as the fixes are now merged. Thanks a lot!