From 358eba79a9380c4b66f49ba456bde7b0c822fb72 Mon Sep 17 00:00:00 2001 From: Alexander Schwartz Date: Sat, 21 Dec 2024 17:22:02 +0100 Subject: [PATCH] Handle YAML parsing errors when showing an editor notification about missing information in the Antora component descriptor (#1753) --- CHANGELOG.adoc | 1 + ...ponentNameMissingNotificationProvider.java | 63 +++++++++++++++++-- 2 files changed, 60 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.adoc b/CHANGELOG.adoc index 4fc37f595..c02e78b23 100644 --- a/CHANGELOG.adoc +++ b/CHANGELOG.adoc @@ -12,6 +12,7 @@ This document provides a high-level view of the changes introduced by release. - Update docs and templates to recommend an absolute path for the `pdf-themesdir` (#1750) - When rendering the preview for Antora, automatically switch to highlight.js syntax highlighting (#1736) - Make wrap-on-typing work for AsciiDoc without chopping an existing line into small chunks (#1653) +- Handle YAML parsing errors when showing an editor notification about missing information in the Antora component descriptor (#1753) === 0.43.4 diff --git a/src/main/java/org/asciidoc/intellij/editor/notification/AntoraComponentNameMissingNotificationProvider.java b/src/main/java/org/asciidoc/intellij/editor/notification/AntoraComponentNameMissingNotificationProvider.java index c7f0109e0..f509f70c2 100644 --- a/src/main/java/org/asciidoc/intellij/editor/notification/AntoraComponentNameMissingNotificationProvider.java +++ b/src/main/java/org/asciidoc/intellij/editor/notification/AntoraComponentNameMissingNotificationProvider.java @@ -7,15 +7,23 @@ import com.intellij.openapi.project.DumbAware; import com.intellij.openapi.project.Project; import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.VirtualFileManager; +import com.intellij.openapi.vfs.newvfs.BulkFileListener; +import com.intellij.openapi.vfs.newvfs.events.VFileEvent; import com.intellij.ui.EditorNotificationPanel; import com.intellij.ui.EditorNotificationProvider; +import com.intellij.ui.EditorNotifications; +import com.intellij.util.messages.MessageBusConnection; import org.asciidoc.intellij.AsciiDocWrapper; import org.asciidoc.intellij.file.AsciiDocFileType; import org.asciidoc.intellij.psi.AsciiDocUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.yaml.snakeyaml.error.YAMLException; +import org.yaml.snakeyaml.scanner.ScannerException; import javax.swing.*; +import java.util.List; import java.util.Map; import java.util.function.Function; @@ -40,10 +48,20 @@ public class AntoraComponentNameMissingNotificationProvider implements EditorNot if (antoraFile == null) { return null; } - antora = AsciiDocWrapper.readAntoraYaml(project, antoraFile); + try { + antora = AsciiDocWrapper.readAntoraYaml(project, antoraFile); + } catch (YAMLException ex) { + return prepareMessageFromException("Can't read Antora component descriptor 'antora.yml': ", + ex, file, antoraFile, project); + } } else if (file.getName().equals(ANTORA_YML)) { antoraFile = file; - antora = AsciiDocWrapper.readAntoraYaml(project, file); + try { + antora = AsciiDocWrapper.readAntoraYaml(project, file); + } catch (YAMLException ex) { + return prepareMessageFromException("Can't read Antora component descriptor 'antora.yml': ", + ex, file, antoraFile, project); + } } else { return null; } @@ -52,16 +70,53 @@ public class AntoraComponentNameMissingNotificationProvider implements EditorNot return null; } + return prepareMessageFromException("The Antora component descriptor 'antora.yml' is missing the attribute 'name'" + + ".", null, file, antoraFile, project); + } + + private static @NotNull Function<@NotNull FileEditor, @Nullable JComponent> prepareMessageFromException(String message, RuntimeException ex, @NotNull VirtualFile file, VirtualFile antoraFile, @NotNull Project project) { return fileEditor -> { final EditorNotificationPanel panel = new EditorNotificationPanel(); - panel.setText("The Antora component descriptor 'antora.yml' is missing the attribute 'name'."); + String m = message; + if (ex instanceof ScannerException scannerException) { + m = m + scannerException.getProblem(); + } else if (ex != null) { + m = m + ex.getMessage(); + } if (!file.equals(antoraFile)) { - panel.createActionLabel("Open 'antora.yml'", () + if (ex instanceof ScannerException scannerException) { + panel.createActionLabel("Open 'antora.yml'", () + -> ApplicationManager.getApplication().invokeLater(() + -> new OpenFileDescriptor(project, antoraFile, scannerException.getProblemMark().getLine(), + scannerException.getProblemMark().getColumn()).navigate(true))); + } else { + panel.createActionLabel("Open 'antora.yml'", () -> ApplicationManager.getApplication().invokeLater(() -> new OpenFileDescriptor(project, antoraFile).navigate(true))); + } } + panel.setText(m); panel.createActionLabel("Read more...", () -> BrowserUtil.browse("https://docs.antora.org/antora/latest/component-version-descriptor/")); + + MessageBusConnection connection = ApplicationManager.getApplication().getMessageBus().connect(fileEditor); + connection.subscribe(VirtualFileManager.VFS_CHANGES, new BulkFileListener() { + @Override + public void after(@NotNull List events) { + // any modification of a file within the project refreshes the preview + for (VFileEvent event : events) { + if (event.getFile() != null) { + if (event.getFile().equals(antoraFile)) { + // Also update those in other AsciiDoc editors in the module + EditorNotifications.updateAll(); + connection.disconnect(); + break; + } + } + } + } + }); + return panel; }; }