You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
This repository was archived by the owner on Apr 8, 2020. It is now read-only.
Repository navigation
This repository was archived by the owner on Apr 8, 2020. It is now read-only.
Debug with Angular Universal/prerenderer module #202
I just started a new demo project using the Yeoman template with Angular2.
I have been having some trouble debugging when the prerenderer module is enabled. The main issue here is that we don't get any feedback from the server when there's an issue during prerendering i.e. in the console after running dotnet run.
I've had some moderate success when I made mistakes in my client side code by disabling this in the Home/Index.cshtml file:
But now I'm experiencing a new issue with the same behavior as I had with client side errors (page taking a long time to load followed by an error page), but if I disable prerendering it works fine.
I'm not asking to be helped in solving my particular issue: I'm sure it's a simple mistake I made because I'm new to Angular2. But I do want to know what to do to debug this, and suggest adding more information to the console output about the prerendering process. Maybe just outputting the javascript logs (e.g. console.log, console.error calls) would be enough.
Well, basically any output from server should go directly to your console, so any console.log should work. In universal app i think it only possyble way to do this. You may also try to debug you node code, but it much more harder.
The only clue I get is the following mesage: [Node] WARNING: your application is taking a long time to render the application and then System.Threading.Tasks.TaskCanceledException: A task was canceled.
@tinchou I ran into the same issue myself when playing with nested routing. Turning off the SpaServices Prerendering tag helper did the trick. Also, alternatively removing all bindings on the nested template prevented it from timing out. My guess is it has something to do with the async timing of nested levels of component bindings. I wonder if pre-rendering is compatible in that scenario.
On a side note, it would be nice if I had a nice way of setting a break point in the code during node rendering since it is all compiled on the server during a refresh.
I've updated some parts of these libraries so that they support attaching a node-inspector debugger to the Node processes that they launch. This means you can debug through your TypeScript/JavaScript code when it's running on the server.
I'll add full docs for this later, but first, let's see if you can make it work based on these notes :)
Prerequisites
Update your copy of the aspnet-webpack NPM module to the latest version (currently, 1.0.7):
npm install --save aspnet-webpack
Update your copies of the Microsoft.AspNetCore.NodeScriptServices / SpaServices / AngularServices packages to the latest version (currently, 1.0.0-beta-000008). To do this, edit your project.json file to set the correct version on any of those packages that are explicitly referenced. You are probably only referencing AngularServices directly, so edit your project.json to include:
You probably also need to add using Microsoft.AspNetCore.NodeServices; at the top of the file too.
Make sure you're running everything in debug mode. For example, in your command line, set the ASPNETCORE_ENVIRONMENT environment variable to Development.
Now, run your application from that command line (e.g., dotnet run). Then in a browser visit one of your pages that causes server-side JS to execute.
In the console, you should see all the normal trace messages appear, plus among them will be:
-----
*** Node.js debugging is enabled ***
Debugger listening on port 5858
To debug, run:
node-inspector
If you haven't yet installed node-inspector, you can do so as follows:
npm install -g node-inspector
-----
In some other command line window, follow those instructions (i.e., install node-inspector as it describes, then run node-inspector). Then you can open a browser at http://127.0.0.1:8080/?port=5858 and you'll see the debugger UI.
By expanding the webpack:// entry in the sidebar, you'll be able to find your original TypeScript code (it's using source maps), and then set breakpoints in it. When you re-run your app in another browser window, your breakpoints will be hit, then you can debug the server-side execution just like you'd debug client-side execution. It looks like this:
(Note: although this looks like Chrome's native debugger for client-side code, it is actually a JavaScript-powered debugger UI that's connected to the server-side runtime)
Summary
As you can see, getting this to work is all quite delicate and fiddly. Maybe one day it might be possible to use VS Code as the debugging UI, but I'm not sure how far away that might be. If you hit any trouble getting this to work, please let me know!
Reacted by Mark Pieszak, Thomas J. Crowe, Quinntyne Brown, Charalampos Karypidis, Base, sad1y, Siddharth Sharma, Gordian Berger, Boban Stojanovski and Geir Sagberg
@SteveSandersonMS This looks amazing! Great Job! I tried it out for myself and I am running into problems with node.exe failing to initialize. Do you have any idea what might be happening?
fail: Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware[0]
An unhandled exception has occurred while executing the request
System.InvalidOperationException: The Node.js process failed to initialize: Debugger listening on [::]:5858
Ah yes, I think I see what's wrong. It looks like Node behaves slightly differently in an IPv6 environment, which appears to be the case for you given the error message you got.
I've made a fix and published it as Microsoft.AspNetCore.NodeServices version 1.0.0-beta-000009. Could you try updating to that and see if it starts working?
@SteveSandersonMS It works! And here I thought I didn't provide enough diagnostic information. I can confirm that I am in fact configured to use IPv6 with IPv4 as fallback. You should know that this solution only works when I open my chrome browser to the above address. When attempting to open in Edge, I receive the following error in my browser's console:
"Unknown experiment canvasInspection"
I assume this has something to do with EdgeHTML 13 not on feature parity with Chrome 52 (current versions as of now). What is this "canvasInspection" anyways? I guess a feature request is now in order to make node-inspector compatible with other browsers or to add this canvasInspection API to Edge. Any suggestions on the best route to enable node-inspector on the Edge browser?
Any suggestions on the best route to enable node-inspector on the Edge browser
Contact the node-inspector project folks. But bear in mind that the debugger UI here probably comes from the Chrome project (since it's the same UI that ships in Chrome as the native JS debugger), and they might consider that to be the only important use case.
I'd suggest you just use Chrome for debugging with node-inspector!
I found another two things that are causing me issues with node-inspector.
After loading the page in chrome. The webpack:// tree is missing and in the console tab, it displays a message saying that .\TestSPA\ClientApp\webpack-output.js.map is missing. That's because webpack has it located at .\TestSPA\wwwroot\dist\main.js.map on disk. A simple workaround is to simply copy/paste/rename the map file to the location it is complaining about and reload. The webpack:// route shows up with all the .ts files intact as you demostrated.
I don't know if this is a node inspector issue or not or can be solved on this end but I still haven't gotten breakpoints to work. Seems to be the chicken and egg problem. I need to load webpage to acquire js.map source, which loads the webpack://, so I can select my break points. However, I need to set my breakpoint before loading the webpage, because by then the loading of the page triggers the server rendering. I tried a page refresh with no success (probably because the server rendering is cached). I also tried changing my source code to trigger a recompile, but that seems to freeze up the whole system. I will keep hacking away at it. Don't know if anyone else has ran into that issue.
Works, but I get a lot of InvalidOperationException: The Node.js process failed to initialize: Error: listen EADDRINUSE :::5858 errors after hmr and rhmr do their thing. Any ideas? This is without anything attaching to 5858.
EADDRINUSE errors just imply there's still some earlier Node process listening on the same port. You'll need to ensure all previous instances are properly stopped before you can start a new one. If you're on Linux/OS X (guessing you are from the phrasing of the message) then it might be enough just to run pkill node.
This is without anything attaching to 5858.
Are you really sure? Try sudo ps -A | grep node to confirm whether there really are any hidden instances still alive. If you're able to confirm there's really nothing listening on 5858 but still get this, are you able to supply any repro steps?
Yeah I tried closing all node processes and starting over (I'm actually on windows btw):
Launched a terminal window
set the dotcore environment, then dotnet run
Launch vscode and attach to process.
It works fine but after a few HMR/webpack rebuilding cycles, the error eventually manifests (and multiple node instances as well, 3 when originally there were 1).
Just a quick note ... npm install -g node-inspector installation fails on Win10.
Solution is to point to a version ... this works : npm install -g node-inspector@0.7.4
Activity
laskoviymishka commentedon Jul 21, 2016
Well, basically any output from server should go directly to your console, so any console.log should work. In universal app i think it only possyble way to do this. You may also try to debug you node code, but it much more harder.
colltoaction commentedon Jul 21, 2016
The only clue I get is the following mesage:
[Node] WARNING: your application is taking a long time to render the applicationand thenSystem.Threading.Tasks.TaskCanceledException: A task was canceled.How could I debug that?
laskoviymishka commentedon Jul 21, 2016
What is your setup for prerendering? Default options? Can you try to change protocol to
Httpfrom default sockets.colltoaction commentedon Jul 22, 2016
I ran the yeoman aspnetcore-spa generator with Angular2 and I haven't touched the
boot-server.tsfile.How can I change the protocol to default sockets? I looked around and googled it, but can't find anything.
wizarrc commentedon Jul 26, 2016
@tinchou I ran into the same issue myself when playing with nested routing. Turning off the SpaServices Prerendering tag helper did the trick. Also, alternatively removing all bindings on the nested template prevented it from timing out. My guess is it has something to do with the async timing of nested levels of component bindings. I wonder if pre-rendering is compatible in that scenario.
On a side note, it would be nice if I had a nice way of setting a break point in the code during node rendering since it is all compiled on the server during a refresh.
SteveSandersonMS commentedon Jul 26, 2016
I've updated some parts of these libraries so that they support attaching a
node-inspectordebugger to the Node processes that they launch. This means you can debug through your TypeScript/JavaScript code when it's running on the server.I'll add full docs for this later, but first, let's see if you can make it work based on these notes :)
Prerequisites
Update your copy of the
aspnet-webpackNPM module to the latest version (currently, 1.0.7):Update your copies of the
Microsoft.AspNetCore.NodeScriptServices/SpaServices/AngularServicespackages to the latest version (currently, 1.0.0-beta-000008). To do this, edit yourproject.jsonfile to set the correct version on any of those packages that are explicitly referenced. You are probably only referencing AngularServices directly, so edit yourproject.jsonto include:... and then, from your project root directory, run:
Enabling debugging
In your
Startup.csfile, in theConfigureServicesmethod, add the following:You probably also need to add
using Microsoft.AspNetCore.NodeServices;at the top of the file too.Make sure you're running everything in debug mode. For example, in your command line, set the
ASPNETCORE_ENVIRONMENTenvironment variable toDevelopment.Now, run your application from that command line (e.g.,
dotnet run). Then in a browser visit one of your pages that causes server-side JS to execute.In the console, you should see all the normal trace messages appear, plus among them will be:
In some other command line window, follow those instructions (i.e., install
node-inspectoras it describes, then runnode-inspector). Then you can open a browser athttp://127.0.0.1:8080/?port=5858and you'll see the debugger UI.By expanding the
webpack://entry in the sidebar, you'll be able to find your original TypeScript code (it's using source maps), and then set breakpoints in it. When you re-run your app in another browser window, your breakpoints will be hit, then you can debug the server-side execution just like you'd debug client-side execution. It looks like this:(Note: although this looks like Chrome's native debugger for client-side code, it is actually a JavaScript-powered debugger UI that's connected to the server-side runtime)
Summary
As you can see, getting this to work is all quite delicate and fiddly. Maybe one day it might be possible to use VS Code as the debugging UI, but I'm not sure how far away that might be. If you hit any trouble getting this to work, please let me know!
wizarrc commentedon Jul 27, 2016
@SteveSandersonMS This looks amazing! Great Job! I tried it out for myself and I am running into problems with node.exe failing to initialize. Do you have any idea what might be happening?
fail: Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware[0]
An unhandled exception has occurred while executing the request
System.InvalidOperationException: The Node.js process failed to initialize: Debugger listening on [::]:5858
SteveSandersonMS commentedon Jul 27, 2016
Ah yes, I think I see what's wrong. It looks like Node behaves slightly differently in an IPv6 environment, which appears to be the case for you given the error message you got.
I've made a fix and published it as Microsoft.AspNetCore.NodeServices version 1.0.0-beta-000009. Could you try updating to that and see if it starts working?
wizarrc commentedon Jul 27, 2016
@SteveSandersonMS It works! And here I thought I didn't provide enough diagnostic information. I can confirm that I am in fact configured to use IPv6 with IPv4 as fallback. You should know that this solution only works when I open my chrome browser to the above address. When attempting to open in Edge, I receive the following error in my browser's console:
"Unknown experiment canvasInspection"
I assume this has something to do with EdgeHTML 13 not on feature parity with Chrome 52 (current versions as of now). What is this "canvasInspection" anyways? I guess a feature request is now in order to make node-inspector compatible with other browsers or to add this canvasInspection API to Edge. Any suggestions on the best route to enable node-inspector on the Edge browser?
SteveSandersonMS commentedon Jul 27, 2016
Contact the node-inspector project folks. But bear in mind that the debugger UI here probably comes from the Chrome project (since it's the same UI that ships in Chrome as the native JS debugger), and they might consider that to be the only important use case.
I'd suggest you just use Chrome for debugging with node-inspector!
wizarrc commentedon Jul 27, 2016
@SteveSandersonMS I thought that is what you would say. Bummer!
I found another two things that are causing me issues with node-inspector.
colltoaction commentedon Jul 28, 2016
It works great! It really helped me identify some issues in the backend. Looks good to close, but don't forget to document this somewhere!
onethread commentedon Aug 8, 2016
Works, but I get a lot of
InvalidOperationException: The Node.js process failed to initialize: Error: listen EADDRINUSE :::5858errors after hmr and rhmr do their thing. Any ideas? This is without anything attaching to 5858.SteveSandersonMS commentedon Aug 16, 2016
EADDRINUSEerrors just imply there's still some earlier Node process listening on the same port. You'll need to ensure all previous instances are properly stopped before you can start a new one. If you're on Linux/OS X (guessing you are from the phrasing of the message) then it might be enough just to runpkill node.Are you really sure? Try
sudo ps -A | grep nodeto confirm whether there really are any hidden instances still alive. If you're able to confirm there's really nothing listening on 5858 but still get this, are you able to supply any repro steps?onethread commentedon Aug 16, 2016
Yeah I tried closing all node processes and starting over (I'm actually on windows btw):
It works fine but after a few HMR/webpack rebuilding cycles, the error eventually manifests (and multiple node instances as well, 3 when originally there were 1).
vbilici commentedon Sep 12, 2016
I am using windows and the same issue happens after code change and node restart when debugging enabled.
SteveSandersonMS commentedon Oct 21, 2016
Docs are now added here: https://github.com/aspnet/JavaScriptServices/tree/dev/src/Microsoft.AspNetCore.SpaServices#debugging-your-javascripttypescript-code-when-it-runs-on-the-server
boban100janovski commentedon Mar 28, 2017
Just a quick note ...
npm install -g node-inspectorinstallation fails on Win10.Solution is to point to a version ... this works :
npm install -g node-inspector@0.7.4