Skip to content

api.render() throws exception when called from anonymous functions #4774

Closed
@philcal

Description

@philcal

Version

4.0.5

Environment info

System:
    OS: macOS 10.15
    CPU: (8) x64 Intel(R) Core(TM) i7-7820HQ CPU @ 2.90GHz
  Binaries:
    Node: 12.10.0 - /usr/local/bin/node
    Yarn: 1.7.0 - /usr/local/bin/yarn
    npm: 6.11.3 - /usr/local/bin/npm
  Browsers:
    Chrome: 78.0.3904.70
    Firefox: 57.0.4
    Safari: 13.0.2
  npmGlobalPackages:
    @vue/cli: Not Found

Steps to reproduce

If the render function is called from within an anonymous function, an exception occurs. Typically this might happen in a callback, but the following examples demonstrate the problem.

    (() => { // ANONYMOUS FUNCTION
        api.render('./template')     // EXCEPTION
    })()
    
    (function() { // ANONYMOUS FUNCTION
        api.render('./template')     // EXCEPTION
    })()
    
    (function isCompleted() { // NAMED FUNCTION
        api.render('./template')     // WORKS CORRECTLY
    })()

What is expected?

It should be possible to call api.render() from within an anonymous function.

What is actually happening?

An exception is thrown when api.render() is called from within an anonymous function. This occurs because the stack trace used by extractCallDir() to get the project directory does not contain parenthesis:

ERROR  TypeError: Cannot read property '1' of null  
TypeError: Cannot read property '1' of null  
     at extractCallDir (/Users/philcal/.config/yarn/global/node_modules/@vue/cli/lib/GeneratorAPI.js:406:57)  
     at GeneratorAPI.render (/Users/philcal/.config/yarn/global/node_modules/@vue/cli/lib/GeneratorAPI.js:227:21)  

[THE FOLLOWING LINE CONTAINS NO PARENTHESES]

     at /private/tmp/my-project/node_modules/vue-cli-plugin-xyz/generator/index.js:39:9
     at runGenerator (/Users/philcal/.config/yarn/global/node_modules/@vue/cli/lib/invoke.js:141:13)  
     at processTicksAndRejections (internal/process/task_queues.js:93:5)  
     at async invoke (/Users/philcal/.config/yarn/global/node_modules/@vue/cli/lib/invoke.js:101:3)  

Workaround:
In the plugin code, give a name to the anonymous function that calls api.render(), however that solution is not obvious to a person experiencing this problem.

Full resolution:
The function extractCallDir() should handle stack trace lines for anonymous functions, but the line containing callSite.match(..) only matches lines containing parentheses. (See stack trace example above)

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions