parser-js: Recursive messages cause the parser to stack overflow

Describe the bug

I need to define messages that are recursive tree structures. When I do this and attempt to use the @asyncapi/generator, to generate documentation (or code) for my spec, the parser fails with a Error: Maximum call stack size exceeded message.

How to Reproduce

Here’s a minimal asyncapi spec that reproduces the issue:

asyncapi: '2.0.0'
info:
  title: Example
  version: 0.1.1
channels:
  recursive:
    subscribe:
      message:
        payload:
          $ref: '#/components/schemas/Recursive'
components:
  schemas:
    Recursive:
      type: object
      properties:
        children:
          type: array
          items:
            $ref: '#/components/schemas/Recursive'
        # This also causes a stack overflow
        # child:
        #   $ref: '#/components/schemas/Recursive'
        something:
          type: string
$ npx -p @asyncapi/generator ag ./recursive.yaml @asyncapi/html-template --force-write -o docs
npx: installed 213 in 8.774s
Something went wrong:
Error: Maximum call stack size exceeded
    at parse (~/.npm/_npx/32509/lib/node_modules/@asyncapi/generator/node_modules/@asyncapi/parser/lib/parser.js:121:11)
    at async Generator.generateFromString (~/.npm/_npx/32509/lib/node_modules/@asyncapi/generator/lib/generator.js:233:21)
    at async /~/.npm/_npx/32509/lib/node_modules/@asyncapi/generator/cli.js:150:9

Expected behavior

I would expect the parser to be able to handle recursive messages.

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Comments: 32 (27 by maintainers)

Most upvoted comments

@nsnichols no worries. Sorry for the confusion, it is because when I worked on more complex example and did some copy/paste I did not change children to something else, so in one schema it is array and in another it is object:

asyncapi: '2.0.0'
info:
  title: Example
  version: 0.1.1
channels:
  recursive:
    subscribe:
      message:
        payload:
          $ref: '#/components/schemas/Recursive'
components:
  schemas:
    Recursive:
      type: object
      properties:
        children:
          type: array
          items:
            $ref: '#/components/schemas/Recursive'
        something:
          type: object
          properties:
            maryna:
              $ref: '#/components/schemas/RecursiveNext'
    RecursiveNext:
      type: object
      properties:
        children:
          type: object
          properties:
            maniek:
              $ref: '#/components/schemas/RecursiveNext'
            ulala:
              type: string

We will wait a week or 2 for the merge of my PR to openapi-sampler and once it is done, the PRs to html and markdown templates will be merged

jsonschema-sampler so it’s also valid for other people/projects.

Reopen because of my comment. Let us wait what will be the response under https://github.com/Redocly/openapi-sampler/issues/113 to make sure no more things to do in the parser and rest is only in other repos

@nsnichols would be awesome if you could have a look at #94 and proposed way of handling circular refs.

tl;dr in case of circular ref we would return this info '$.components.schemas.RecursiveSelf' so user can figure out from this information that it is circular ref and where it is pointing.

It is hard to come up with something more meaningful without real-world use case but this PR is making a good foundation for future improvements imho