SAP/ui5-tooling

Since upgrade to @ui5/server@3.2.0 ui5 serve fails with TypeError: Cannot read properties of null

danielang-ortec opened this issue · 7 comments

Expected Behavior

ui5 serve should deliver all manifest.json files regardless if it generates them on the fly or serves an existing one.

Current Behavior

In our project we developed our own typescript control library. The library is build by the ui5-tooling. During build time a manifest.json is generated by the task generateLibraryManifest. The library is published to our internal npm registry.
This library is added to our project.

With the last version 3.9.2 ui5 serve worked perfectly. With the update to 3.10.x the new @ui5/server version 3.2.0 was pulled, which contains the following error: TypeError: Cannot read properties of null (reading 'setProject') (Stack Trace attached)

It is in the file node_modules\@ui5\cli\node_modules\@ui5\server\lib\middleware\helper\generateLibraryManifest.js where createManifestProcessor is called. This method resolves to null if it detects that a manifest.json already exists.
On this returned value setProject(project) will be called. This results in the mentioned TypeError since this value could be null.

Temporary Solution: When modifiying the function call to res?.setProject(project); the error does not occure anymore and my app loads again.

Sidenote: You should maybe consider to pin the dependecies of @ui5/cli; downgrading to the previously working 3.9.2 version is not working because "@ui5/server": "^3.1.5" now resolves to 3.2.0 due to the ^. I would expect at least ~ or a direct version. Thank you for considering.

Steps to Reproduce the Issue

  1. Create a custom library that includes a manifest.json descriptor
  2. Use the library in your application
  3. 🧨

Context

  • UI5 Module Version (output of ui5 --version when using the CLI): 3.10.1
  • Node.js Version: v20.11.0
  • npm Version: 9.3.0
  • OS/Platform: Windows 10 x64
  • Browser (if relevant): unknown
  • Other information regarding your environment (optional): nothing

Log Output / Stack Trace

$>npx ui5 serve          
info graph:helpers:ui5Framework Using SAPUI5 version: 1.120.13
info fiori-tools-proxy Starting fiori-tools-proxy using following configuration:
info fiori-tools-proxy proxy: 'undefined'
info fiori-tools-proxy ignoreCertError: 'false'
info fiori-tools-proxy backend: [{"path":"/sap","url":"https://host.intranet:8443"}]
info fiori-tools-proxy ui5: []
info fiori-tools-proxy debug: 'false'
info backend-proxy-middleware Backend proxy created for https://host.intranet:8443 /sap
info fiori-tools-appreload Livereload middleware started for port 35729 and path C:\..\..\webapp
info fiori-tools-preview Initialized for app com.my.secret.app
info server:custom-middleware:ui5-tooling-transpile-middleware Create Babel configuration based on ui5.yaml configuration options...
info server:custom-middleware:ui5-tooling-transpile-middleware Using browserslist configuration from ui5.yaml...
Server started
URL: http://localhost:8080
info backend-proxy-middleware /sap/bc/ui2/app_index/ui5_app_info?id=tplPlanningSuite
info backend-proxy-middleware /sap/bc/ui2/app_index/ui5_app_info?id=tplPlanningSuite
TypeError: Cannot read properties of null (reading 'setProject')
    at generateLibraryManifest (file:///C:/../../node_modules/@ui5/cli/node_modules/@ui5/server/lib/middleware/helper/generateLibraryManifest.js:16:6)
    at async file:///C:/../../node_modules/@ui5/cli/node_modules/@ui5/server/lib/middleware/versionInfo.js:34:24
    at async Promise.all (index 0)
    at async versionInfo (file:///C:/../../node_modules/@ui5/cli/node_modules/@ui5/server/lib/middleware/versionInfo.js:44:25)

Thank you for reporting @danielang-ortec. We are preparing a fix for this issue.

Have you tried downgrading UI5 CLI to the last working version you have mentioned?

Even though the package.json specifies a range for @ui5/server, we publish the CLI package with an npm-shrinkwrap.json which pins the server dependency. In my test npm i -D @ui5/cli@3.9.2 installs @ui5/server@3.1.5.

@RandomByte Thank you.

npm i -D @ui5/cli@3.9.2 did the trick; just changing back the version in the package.json and running npm i wasn't enough.

That's good to know, thanks. Sadly npm often shows inconsistent or unexpected behavior with shrinkwraps.

Coming back to the issue, I understand the cause of the exception (the manifestCreator module does not return a manifest resource) and I agree with you that the middleware should handle this case.

What I'm not sure about is the exact cause of this in your project setup. If a manifest.json exists in the custom library, the generateLibraryManifest module shouldn't be called at all: https://github.com/SAP/ui5-server/blob/39fb46fdeddb3a22d0b7e2abbc092add448561e7/lib/middleware/versionInfo.js#L33-L35

I confirmed this locally with an application depending on a library that already contains a manifest.json. No error occurs and the /resources/sap-ui-version.json is generated and served correctly.

  1. Would it be possible for you to reproduce the issue again and share the full log output (after starting the server with verbose logging: ui5 serve --verbose)?
  2. Can you confirm that requesting http://localhost:8080/resources/sap-ui-version.json fails?
  3. In your application project's ui5.yaml, is there any custom middleware configured?

If possible, a stripped down sample of the problematic library would be great to analyze this further. I hope you understand that I find it important to understand the root cause before implementing a fix.

Our library exposes itself as type module.
The reason is that we dont want to modify the resources that are delivered by the Fiori Launchpad and consume our library from a different resource root.

Thus the following configuration is used:

specVersion: '3.2'
metadata:
  name: "com.my.lib"
type: module
resources:
  configuration:
    paths:
      /resources/com/my/lib/: ./dist/resources/com/my/lib/
      /thirdparty/com/my/lib/: ./dist/resources/com/my/lib/

When debugging the versionInfo middleware it seams like you are trying to resolve the path of the manifest by namespace which isn't working: namespace = null

image

@1: I tried it, but it was logged so much that the relevant lines were quickly exceeding the lines buffer of my console. I could try to log into a file if it is really required.

@2: Returns the error:

TypeError: Cannot read properties of null (reading 'setProject')
    at generateLibraryManifest (file:///C:/development/repositories/ortec-transportation-planning/tpl-ui/planning/node_modules/@ui5/server/lib/middleware/helper/generateLibraryManifest.js:16:6)
    at async file:///C:/development/repositories/ortec-transportation-planning/tpl-ui/planning/node_modules/@ui5/server/lib/middleware/versionInfo.js:34:24
    at async Promise.all (index 0)
    at async versionInfo (file:///C:/development/repositories/ortec-transportation-planning/tpl-ui/planning/node_modules/@ui5/server/lib/middleware/versionInfo.js:44:25)

With my modification from above the content is delivered correctly. It also resolves the version of my library but not the manifestHints

{
	"name": "com.my.app",
	"version": "1.1.2",
	"buildTimestamp": "202405142117",
	"scmRevision": "",
	"libraries": [
		{
			"name": "com.my.lib",
			"version": "1.1.1",
			"buildTimestamp": "202405142117",
			"scmRevision": ""
		},
		{
			"name": "sap.chart",
			"version": "1.120.13",
			"buildTimestamp": "202405142117",
			"scmRevision": "",
			"manifestHints": {
				"dependencies": {
					"libs": {
						"sap.m": {
							"lazy": true
						},
						"sap.ui.core": {},
						"sap.ui.layout": {
							"lazy": true
						},
						"sap.ui.unified": {
							"lazy": true
						},
						"sap.viz": {}
					}
				}
			}
		},
		...
	]
}

@3: Yes, but all from SAP or the community:

server:
  customMiddleware:
    - name: fiori-tools-proxy
      afterMiddleware: compression
      configuration:
        ignoreCertError: false # If set to true, certificate errors will be ignored. E.g. self-signed certificates will be accepted
        backend:
        - path: /sap
          url: https://host.intranet:8443

    - name: fiori-tools-appreload
      afterMiddleware: compression
      configuration:
        port: 35729
        path: webapp
        delay: 300
    - name: fiori-tools-preview
      afterMiddleware: fiori-tools-appreload
      configuration:
        component: com.my.app
        ui5Theme: sap_horizon

    - name: ui5-tooling-transpile-middleware
      afterMiddleware: compression
      configuration:
        debug: true
        transpileAsync: true
        transpileTypeScript: true
        excludePatterns:
          - /Component-preload.js
    - name: ui5-tooling-modules-middleware
      afterMiddleware: ui5-tooling-transpile-middleware
      configuration: &modulesConfig
        addToNamespace: true

Our library exposes itself as type module.

Thanks. This was the missing piece of information for me 👍

Projects of type module should be ignored by the versionInfo middleware (the generateVersionInfo build task ignores them too).

I've prepared a fix that should resolve this regression for you.

The fix was released with @ui5/cli@v3.10.2. Please let us know once you find time to test and confirm the fix. Thanks again for reporting!

Confirmation: It is working.
Thank you very much.