Repository: pyodide/pyodide

Issue:
Documentation build failure
Currently, RTD CI is failing following https://github.com/pyodide/pyodide/pull/3268#issuecomment-1359018099 it looks like `sphinx_js` didn't like something in the changes to the the JS package. I can also reproduce locally.


<details>

```
Error: ../src/js/interface.ts:6:34 - error TS2304: Cannot find name 'PyodideInterface'.

6 API.makePublicAPI = function (): PyodideInterface {
                                   ~~~~~~~~~~~~~~~~

Error: ../src/js/interface.ts:7:3 - error TS2304: Cannot find name 'FS'.

7   FS = Module.FS;
    ~~

Error: ../src/js/interface.ts:8:3 - error TS2304: Cannot find name 'PATH'.

8   PATH = Module.PATH;
    ~~~~

Error: ../src/js/interface.ts:9:3 - error TS2304: Cannot find name 'ERRNO_CODES'.

9   ERRNO_CODES = Module.ERRNO_CODES;
    ~~~~~~~~~~~

Error: ../src/js/interface.ts:11:5 - error TS2552: Cannot find name 'globals'. Did you mean 'global'?

11     globals,
       ~~~~~~~

  ../src/js/node_modules/@types/node/globals.global.d.ts:1:13
    1 declare var global: typeof globalThis;
                  ~~~~~~
    'global' is declared here.

Error: ../src/js/interface.ts:12:5 - error TS18004: No value exists in scope for the shorthand property 'FS'. Either declare one or provide an initializer.

12     FS,
       ~~

Error: ../src/js/interface.ts:13:5 - error TS18004: No value exists in scope for the shorthand property 'PATH'. Either declare one or provide an initializer.

13     PATH,
       ~~~~

Error: ../src/js/interface.ts:14:5 - error TS18004: No value exists in scope for the shorthand property 'ERRNO_CODES'. Either declare one or provide an initializer.

14     ERRNO_CODES,
       ~~~~~~~~~~~

Error: ../src/js/interface.ts:15:5 - error TS18004: No value exists in scope for the shorthand property 'pyodide_py'. Either declare one or provide an initializer.

15     pyodide_py,
       ~~~~~~~~~~

Error: ../src/js/interface.ts:16:5 - error TS18004: No value exists in scope for the shorthand property 'version'. Either declare one or provide an initializer.

16     version,
       ~~~~~~~

Error: ../src/js/interface.ts:17:5 - error TS18004: No value exists in scope for the shorthand property 'loadPackage'. Either declare one or provide an initializer.

17     loadPackage,
       ~~~~~~~~~~~

Error: ../src/js/interface.ts:18:5 - error TS18004: No value exists in scope for the shorthand property 'isPyProxy'. Either declare one or provide an initializer.

18     isPyProxy,
       ~~~~~~~~~

Error: ../src/js/interface.ts:19:5 - error TS18004: No value exists in scope for the shorthand property 'runPython'. Either declare one or provide an initializer.

19     runPython,
       ~~~~~~~~~

Error: ../src/js/interface.ts:20:5 - error TS18004: No value exists in scope for the shorthand property 'runPythonAsync'. Either declare one or provide an initializer.

20     runPythonAsync,
       ~~~~~~~~~~~~~~

Error: ../src/js/interface.ts:21:5 - error TS18004: No value exists in scope for the shorthand property 'registerJsModule'. Either declare one or provide an initializer.

21     registerJsModule,
       ~~~~~~~~~~~~~~~~

Error: ../src/js/interface.ts:22:5 - error TS18004: No value exists in scope for the shorthand property 'unregisterJsModule'. Either declare one or provide an initializer.

22     unregisterJsModule,
       ~~~~~~~~~~~~~~~~~~

Error: ../src/js/interface.ts:23:5 - error TS18004: No value exists in scope for the shorthand property 'setInterruptBuffer'. Either declare one or provide an initializer.

23     setInterruptBuffer,
       ~~~~~~~~~~~~~~~~~~

Error: ../src/js/interface.ts:24:5 - error TS18004: No value exists in scope for the shorthand property 'checkInterrupt'. Either declare one or provide an initializer.

24     checkInterrupt,
       ~~~~~~~~~~~~~~

Error: ../src/js/interface.ts:25:5 - error TS18004: No value exists in scope for the shorthand property 'toPy'. Either declare one or provide an initializer.

25     toPy,
       ~~~~

Error: ../src/js/interface.ts:26:5 - error TS18004: No value exists in scope for the shorthand property 'pyimport'. Either declare one or provide an initializer.

26     pyimport,
       ~~~~~~~~

Error: ../src/js/interface.ts:27:5 - error TS18004: No value exists in scope for the shorthand property 'unpackArchive'. Either declare one or provide an initializer.

27     unpackArchive,
       ~~~~~~~~~~~~~

Error: ../src/js/interface.ts:28:5 - error TS18004: No value exists in scope for the shorthand property 'mountNativeFS'. Either declare one or provide an initializer.

28     mountNativeFS,
       ~~~~~~~~~~~~~

Error: ../src/js/interface.ts:29:5 - error TS18004: No value exists in scope for the shorthand property 'registerComlink'. Either declare one or provide an initializer.

29     registerComlink,
       ~~~~~~~~~~~~~~~

Error: ../src/js/interface.ts:30:5 - error TS18004: No value exists in scope for the shorthand property 'PythonError'. Either declare one or provide an initializer.

30     PythonError,
       ~~~~~~~~~~~

Error: ../src/js/interface.ts:31:5 - error TS18004: No value exists in scope for the shorthand property 'PyBuffer'. Either declare one or provide an initializer.

31     PyBuffer,
       ~~~~~~~~


Traceback (most recent call last):
  File "/home/rth/.miniforge/envs/pyodide-env/lib/python3.10/site-packages/sphinx/events.py", line 94, in emit
    results.append(listener.handler(self.app, *args))
  File "/home/rth/.miniforge/envs/pyodide-env/lib/python3.10/site-packages/sphinx_js/__init__.py", line 60, in analyze
    app._sphinxjs_analyzer = analyzer.from_disk(abs_source_paths,
  File "/home/rth/.miniforge/envs/pyodide-env/lib/python3.10/site-packages/sphinx_js/typedoc.py", line 37, in from_disk
    json = typedoc_output(abs_source_paths,
  File "/home/rth/.miniforge/envs/pyodide-env/lib/python3.10/site-packages/sphinx_js/typedoc.py", line 331, in typedoc_output
    return load(getreader('utf-8')(temp))
  File "/home/rth/.miniforge/envs/pyodide-env/lib/python3.10/json/__init__.py", line 293, in load
    return loads(fp.read(),
  File "/home/rth/.miniforge/envs/pyodide-env/lib/python3.10/json/__init__.py", line 346, in loads
    return _default_decoder.decode(s)
  File "/home/rth/.miniforge/envs/pyodide-env/lib/python3.10/json/decoder.py", line 337, in decode
    obj, end = self.raw_decode(s, idx=_w(s, 0).end())
  File "/home/rth/.miniforge/envs/pyodide-env/lib/python3.10/json/decoder.py", line 355, in raw_decode
    raise JSONDecodeError("Expecting value", s, err.value) from None
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/home/rth/.miniforge/envs/pyodide-env/lib/python3.10/site-packages/sphinx/cmd/build.py", line 272, in build_main
    app = Sphinx(args.sourcedir, args.confdir, args.outputdir,
  File "/home/rth/.miniforge/envs/pyodide-env/lib/python3.10/site-packages/sphinx/application.py", line 256, in __init__
    self._init_builder()
  File "/home/rth/.miniforge/envs/pyodide-env/lib/python3.10/site-packages/sphinx/application.py", line 315, in _init_builder
    self.events.emit('builder-inited')
  File "/home/rth/.miniforge/envs/pyodide-env/lib/python3.10/site-packages/sphinx/events.py", line 102, in emit
    raise ExtensionError(__("Handler %r for event %r threw an exception") %
sphinx.errors.ExtensionError: Handler <function analyze at 0x7f5269aa0ca0> for event 'builder-inited' threw an exception (exception: Expecting value: line 1 column 1 (char 0))

Extension error (sphinx_js):
Handler <function analyze at 0x7f5269aa0ca0> for event 'builder-inited' threw an exception (exception: Expecting value: line 1 column 1 (char 0))
make: *** [Makefile:19: html] Error 2
```
</details>

the other issue (that we cannot do much about) is that when RTD fails it often doesn't show status in particular on main. The build log is in https://readthedocs.org/projects/pyodide/builds/

cc @hoodmane 


Discussion:

Resolving patch:
diff --git a/docs/sphinx_pyodide/sphinx_pyodide/jsdoc.py b/docs/sphinx_pyodide/sphinx_pyodide/jsdoc.py
--- a/docs/sphinx_pyodide/sphinx_pyodide/jsdoc.py
+++ b/docs/sphinx_pyodide/sphinx_pyodide/jsdoc.py
@@ -66,7 +66,11 @@ def destructure_param(param: dict[str, Any]) -> list[dict[str, Any]]:
         child = dict(child)
         if "type" not in child:
             if "signatures" in child:
-                child["comment"] = child["signatures"][0]["comment"]
+                try:
+                    child["comment"] = child["signatures"][0]["comment"]
+                except KeyError:
+                    # TODO: handle no comment case
+                    pass
                 child["type"] = {
                     "type": "reflection",
                     "declaration": dict(child),


Test patch: