Umair
Umair

Reputation: 5461

NodeJs on Azure app service using ASP.NET Core NodeServices does not execute

I have a site on Azure App Service which uses node js to print pdf files.

The site is built on asp.net core and uses NodeServices to call phantomjs library which will be used to convert html page to pdf.

I am using the following code:

public void ConfigureServices(IServiceCollection services)
{
     services.AddNodeServices();
}

And use the below code to invoke the nodejs file:

var result = await _nodeServices.InvokeAsync<bool>("./NodeJs/createPdf.js", pageUrl);

My project solution does contain package.json file as well and it has required dependencies. The solution does work fine on my local machine.

On azure I have set the nodejs version to be the maximum available in the Configuration:

  {
    "name": "WEBSITE_NODE_DEFAULT_VERSION",
    "value": "10.15.2"
  },

When executing this on app services I get the following error:

[2019-05-14 12:15:12 ERR] Connection id "0HLMOCN6RLHIU", Request id "0HLMOCN6RLHIU:00000001": An unhandled exception was thrown by the application.
Microsoft.AspNetCore.NodeServices.HostingModels.NodeInvocationException: Cannot find module 'phantom'
Error: Cannot find module 'phantom'
    at Function.Module._resolveFilename (internal/modules/cjs/loader.js:581:15)
    at Function.Module._load (internal/modules/cjs/loader.js:507:25)
    at Module.require (internal/modules/cjs/loader.js:637:17)
    at require (internal/modules/cjs/helpers.js:22:18)
    at Object.<anonymous> (D:\home\site\wwwroot\NodeJs\createPdf.js:1:79)
    at Module._compile (internal/modules/cjs/loader.js:689:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:700:10)
    at Module.load (internal/modules/cjs/loader.js:599:32)
    at tryModuleLoad (internal/modules/cjs/loader.js:538:12)
    at Function.Module._load (internal/modules/cjs/loader.js:530:3)
   at Microsoft.AspNetCore.NodeServices.HostingModels.HttpNodeInstance.InvokeExportAsync[T](NodeInvocationInfo invocationInfo, CancellationToken cancellationToken)
   at Microsoft.AspNetCore.NodeServices.HostingModels.OutOfProcessNodeInstance.InvokeExportAsync[T](CancellationToken cancellationToken, String moduleName, String exportNameOrNull, Object[] args)
   at Microsoft.AspNetCore.NodeServices.NodeServicesImpl.InvokeExportWithPossibleRetryAsync[T](String moduleName, String exportedFunctionName, Object[] args, Boolean allowRetry, CancellationToken cancellationToken)
   at Microsoft.AspNetCore.NodeServices.NodeServicesImpl.InvokeExportWithPossibleRetryAsync[T](String moduleName, String exportedFunctionName, Object[] args, Boolean allowRetry, CancellationToken cancellationToken)
   at PdfProcessor.Controllers.ProcessToPdfController.Generate(PdfRequestModel model) in d:\a\1\s\PdfProcessor\Controllers\ProcessToPdfController.cs:line 82
   at PdfProcessor.Controllers.ProcessToPdfController.GeneratePdf(String pageUrl) in d:\a\1\s\PdfProcessor\Controllers\ProcessToPdfController.cs:line 52
   at Microsoft.AspNetCore.Mvc.Internal.ActionMethodExecutor.TaskOfIActionResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)
   at System.Threading.Tasks.ValueTask`1.get_Result()
   at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.InvokeActionMethodAsync()
   at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.InvokeNextActionFilterAsync()
   at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Rethrow(ActionExecutedContext context)
   at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
   at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.InvokeInnerFilterAsync()
   at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeNextResourceFilter()
   at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Rethrow(ResourceExecutedContext context)
   at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
   at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeFilterPipelineAsync()
   at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeAsync()
   at Microsoft.AspNetCore.Builder.RouterMiddleware.Invoke(HttpContext httpContext)
   at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.Server.IISIntegration.IISMiddleware.Invoke(HttpContext httpContext)
   at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.ProcessRequests[TContext](IHttpApplication`1 application)

The error seems as if npm install has not been run on app services. I have tried with different node versions and restarted app service but still get the same error.

I have also tried deleting package-lock.json file and republishing the site, but in vain.

Upvotes: 0

Views: 1866

Answers (1)

technogeek1995
technogeek1995

Reputation: 3444

The issue appears to be that the C# runtime cannot find the Node JS dependency phantom. From a Node JS perspective, I think it's likely that the dependency isn't installed because Kudu likely doesn't install dependencies in a C# App Service. This would explain why it works on your machine, but not in the cloud. To get it resolved, try following these steps below:

  1. Launch the Azure Portal and navigate to your App Service > Select Advanced Tools > Go. This should open Kudu Services in a new tab on your browser.
  2. Select Debug Console > PowerShell from the top menu bar
  3. Navigate to site/wwwroot/. You should see your package.json file and a folder called node_modules. This folder stores your Node JS dependencies (eg: phantom). If the node_modules folder is not found, it'll get created with the next step.
  4. From the PowerShell prompt, run npm install.
  5. You should now see the node_modules folder if it was not previously present. Inside it, you should find a lot of folders. However, you should see a phantom in that folder. This would be success.
  6. Restart your App Service and test your function

If you don't have your package.json file, it may not be getting published, in which case you have a different issue.

Upvotes: 1

Related Questions