microsoft / vscode-cordova

A Visual Studio Code extension providing intellisense, debug, and build support for Cordova and Ionic projects.
https://marketplace.visualstudio.com/items?itemName=vsmobile.cordova-tools
Other
293 stars 68 forks source link

[cordova-debug-adapter] TypeError: Cannot read property 'nodeValue' of undefined #58

Closed Ritzlgrmft closed 8 years ago

Ritzlgrmft commented 8 years ago

In between, I am able to debug my app in the simulator (#54). But now I wanted to debug on an attached iPhone. When I select Run iOS on device, I see in the debug console:

Launching for ios (This may take a while)...
Launching app (This may take a while)...
Installing app on device
Launching app

And the I get the error

[cordova-debug-adapter] TypeError: Cannot read property 'nodeValue' of undefined

When I select Attach to running iOS on device, I see in the debug console:

Attaching to ios
Configuring debugging proxy

And then I get the same error as above.

MSLaguana commented 8 years ago

I recall seeing an issue like this when there was a misbehaving plist file... Do you have any plugins in this project? We had a bug in TACO which was triggered by an extension containing a plist file, so it may be the same problem here.

MSLaguana commented 8 years ago

Do you have a platforms/ios/<projectname>/<projectname>-Info.plist file? If so, what happens if you try running /usr/libexec/PlistBuddy -c Print path/to/<projectname>-Info.plist?

Ritzlgrmft commented 8 years ago

The output from PlistBuddy is:

Dict {
    CFBundleName = ${PRODUCT_NAME}
    CFBundleIdentifier = markus.recipes.mobile
    CFBundleInfoDictionaryVersion = 6.0
    CFBundleIcons = Dict {
    }
    CFBundleVersion = 1.1.0
    NSMainNibFile~ipad = 
    CFBundleExecutable = ${EXECUTABLE_NAME}
    LSRequiresIPhoneOS = true
    UIRequiresFullScreen = true
    CFBundleIcons~ipad = Dict {
    }
    CFBundleDisplayName = ${PRODUCT_NAME}
    NSAppTransportSecurity = Dict {
        NSAllowsArbitraryLoads = true
    }
    CFBundlePackageType = APPL
    CFBundleIconFile = icon.png
    CFBundleSignature = ????
    NSMainNibFile = 
    CFBundleDevelopmentRegion = English
    CFBundleShortVersionString = 1.1.0
}

Any yes, I am using some plugins:

<plugin name="cordova-plugin-app-version" spec="~0.1.8" />
<plugin name="cordova-plugin-device" spec="~1.1.1" />
<plugin name="cordova-plugin-dialogs" version="1.2.0" />
<plugin name="cordova-plugin-insomnia" spec="~4.2.0" />
<plugin name="cordova-plugin-statusbar" spec="~2.1.1" />
<plugin name="cordova-plugin-x-socialsharing" spec="~5.0.10" />
MSLaguana commented 8 years ago

That plist file seems fine, and none of those plugins mess around with plists so they shouldn't be the cause.

There's one other place that we look at plists, which could possibly break:

Could you please run ideviceinstaller -l -o xml > /tmp/$$.ideviceinstaller && echo /tmp/$$.ideviceinstaller to create a listing of all installed apps on your device, and then try /usr/libexec/PlistBuddy -c Print /tmp/<pid>.ideviceinstaller to see if it can parse that file?

Ritzlgrmft commented 8 years ago

It seems that PlistBuddy did not have any problems with the file. I got no errors, only a very long output.

MSLaguana commented 8 years ago

I've double checked and I'm fairly certain that it must be that area that is failing, but it may be due to the specific dependency that we use.

If you look at the <pid>.ideviceinstaller file, is it xml-like, or is it a binary format? And finally, if you have time could you please try the following:

If that does cause an exception, then we'll need to move to using a different dependency.

Ritzlgrmft commented 8 years ago

Indeed, here I get the error:

TypeError: Cannot read property 'nodeValue' of undefined
    at parsePlistXML (/private/tmp/test-plist/node_modules/plist-with-patches/lib/plist.js:149:29)
    at parsePlistXML (/private/tmp/test-plist/node_modules/plist-with-patches/lib/plist.js:125:13)
    at parsePlistXML (/private/tmp/test-plist/node_modules/plist-with-patches/lib/plist.js:139:12)
    at parsePlistXML (/private/tmp/test-plist/node_modules/plist-with-patches/lib/plist.js:127:22)
    at parsePlistXML (/private/tmp/test-plist/node_modules/plist-with-patches/lib/plist.js:139:12)
    at parsePlistXML (/private/tmp/test-plist/node_modules/plist-with-patches/lib/plist.js:113:20)
    at Object.exports.parseStringSync (/private/tmp/test-plist/node_modules/plist-with-patches/lib/plist.js:82:11)
    at Object.exports.parseFileSync (/private/tmp/test-plist/node_modules/plist-with-patches/lib/plist.js:19:19)
    at repl:1:4
    at REPLServer.defaultEval (repl.js:252:27)
MSLaguana commented 8 years ago

Looks like that's the issue then. We'll have to see about moving to a different dependency.

I suspect that I know what is causing your issue though: Would you mind checking the output for the '&' character (grep '&' /tmp/<pid>.ideviceinstaller)? If I'm right, you have installed a version of your app with the & character in its name, and it isn't being properly escaped so the xml is malformed. If that's correct, a temporary workaround would be to uninstall that app.

Ritzlgrmft commented 8 years ago

In my app, I removed the '&' in between. But I found another app in the file:

<key>CFBundleName</key>
<string>Touch&amp;Travel</string>

I uninstalled the app, when I now try to Run iOS on device, I see in the debug console:

Launching for ios (This may take a while)...
Launching app (This may take a while)...
Installing app on device

And then, nothing else happens. Launching app does not appear, so I am not sure, if the problem is really solved.

MSLaguana commented 8 years ago

In this case it sounds like ideviceinstaller is not completing. We are trying to run ideviceinstaller -i platforms/ios/build/device/<appname>.ipa to install the app on the device, and we should print something as soon as it either succeeds or fails. You could try running that command yourself and see if it is hanging.

Sorry you're encountering so much trouble with our extension.

Ritzlgrmft commented 8 years ago

ideviceinstaller -i was working without problems - and also very fast. Afterwards I got in vscode again [cordova-debug-adapter] TypeError: Cannot read property 'nodeValue' of undefined.

MSLaguana commented 8 years ago

I just followed up on the stack trace you gave above, and it looks like the plist file ideviceinstaller is producing has an empty key for some reason, and that confuses the plist parsing library that we use. The library has a fix, but it's not published yet.

WendySanarwanto commented 8 years ago

Hello All,

I could replicate the issue reported by @Ritzlgrmft as well. Here's my current environment:

Cheer.

MSLaguana commented 8 years ago

This is a bug in https://www.npmjs.com/package/plist which has a fix in their github repo, but has not yet been published. I was hoping that they would publish an updated version soon, but it's been a while since they made the fix and it hasn't been updated yet.

MSLaguana commented 8 years ago

For a workaround, you can try the following:

That should update to a version of the plist package which has the required fix.

WendySanarwanto commented 8 years ago

Hello @MSLaguana ,

Thanks for summarising the temporary workaround for this issue. I have followed your suggestions and confirmed the issue does not happen anymore.

image

Cheers.

guillaumejenkins commented 8 years ago

Because this is an external bug that has been fixed, and there is a workaround (as described by @MSLaguana) while waiting for the plist package to publish the fix, I will close this.

eusthace811 commented 8 years ago

Hi!

In my case I am having the following issue after last updates (before it was working with the MSLaguana solution):

pl.parseFileSync is not a function

Any help, please?

MSLaguana commented 8 years ago

Do you mean specifically after making the change I referenced above it is breaking?

It looks like plist has put out an update, but they longer support the parseFileSync option. I'll re-open this issue so we can work on taking that new version and making the required code changes.

From a quick look, I think that parseFileSync should now just be parse, so you can try making that change and see it if works in the short term.

MSLaguana commented 8 years ago

Sorry, I meant to say that parseFileSync(...) should be parse(fs.readFileSync(...)); it no longer handles reading the file just the parsing.

eusthace811 commented 8 years ago

Ahh, yes, after update and make the changes you've suggested above.

I will try to change it!

parse(fs.readFileSync(...));
eusthace811 commented 8 years ago

New problem after change to

var plist = pl.parse(fs.readFileSync( path.join(projectRoot, 'platforms', 'ios', projectName, projectName + '-Info.plist') ));

ERROR: source.substring is not a function

Any help? :(

MSLaguana commented 8 years ago

You may need to cast the readFileSync to a string; try var filename = (...); pl.parse(fs.readFileSync(filename).toString()).

eusthace811 commented 8 years ago

Ok, it works!

cordovaIosDeviceLauncher.js Changes:

Line 8: var pl = require('plist');

Line 34: var filename = path.join(projectRoot, 'platforms', 'ios', projectName, projectName + '-Info.plist'); var plist = pl.parse(fs.readFileSync(filename).toString());

Line 90: var list = pl.parse(fs.readFileSync(filename).toString());

Thank you @MSLaguana !

TimBarham commented 8 years ago

Also if you pass readFileSync() an encoding option it will return a string (rather than a buffer):

pl.parse(fs.readFileSync(filename, 'utf8'));
jicongw commented 8 years ago

Fix is in. Close the issue now.