[IGN-17532]NPE in ViewNode.onChildrenSelected after calling IgnitionDesigner.updateProject() from a module

I know this is probably an un-documented approach to refreshing the Project Browser, but I'm wondering if this is considered a bug that could be fixed to enable this functionality.

I maintain an open-source Designer module (Flint Designer Bridge) that lets VS Code push external edits to project contents into a running Designer (in this case Perspective Views). When a file is saved in VS Code, the extension sends a project.scan request to our module over a local WebSocket; the module asks the gateway to rescan the project files, then refreshes the Designer by calling IgnitionDesigner.updateProject() on the EDT:

SwingUtilities.invokeAndWait(
() -> {
designer.updateProject();
logger.info("Designer project refresh completed");
});

The Designer picks up external changes immediately, same as accepting the built-in "project update available" notification. But there's one case that consistently produces an uncaught exception:

  1. A Perspective view is open in the Designer, with its component child nodes expanded in the Project Browser.
  2. That view's view.json is modified externally (saved from VS Code), and our module triggers the refresh above.
  3. The user clicks one of the component child nodes under that view in the Project Browser.

This throws on the EDT:

Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException:
Cannot invoke "...ViewResourceEditor.getBridge()" because "this.editor" is null
    at com.inductiveautomation.perspective.designer.workspace.nav.ViewNode.onChildrenSelected(ViewNode.java:354)
    at com.inductiveautomation.ignition.designer.navtree.model.AbstractNavTreeNode.dispatchSelectionEvent(AbstractNavTreeNode.java:856)
    ...

From poking at the perspective-designer classes with AI, ViewNode.onChildrenSelected calls this.editor.getBridge() as its first statement with no null check, and editor is only set in onEditorOpened and nulled when the editor closes. So when the project update reloads the externally modified view, its component nodes can still be sitting in the tree with a null editor, and the next click on one NPEs.

Two questions:

  1. Is calling IgnitionDesigner.updateProject() from a module a reasonable/supported way to refresh the Designer after external resource changes, or is there a better API for this?
  2. Is my digging around assessment of the missing null check in ViewNode.onChildrenSelected an actual bug or am I missing something here?

As always, appreciate any help.

Ditto. Thanks for Flint!

I created a ticket for this.
It's technically a bug on our side, though the fact no one else has reported it makes me suspicious :smiley: