From 8ce3dc5d4189ddd656e6f7394af299170e08be49 Mon Sep 17 00:00:00 2001 From: Martin Kouba Date: Mon, 11 Nov 2024 14:56:20 +0100 Subject: [PATCH] QuteErrorPageSetup: support templates that are not backed by a file - fixes #44412 --- .../qute/deployment/QuteDevModeProcessor.java | 31 +++++++++++++++++++ .../runtime/devmode/QuteErrorPageSetup.java | 17 ++++++++++ 2 files changed, 48 insertions(+) create mode 100644 extensions/qute/deployment/src/main/java/io/quarkus/qute/deployment/QuteDevModeProcessor.java diff --git a/extensions/qute/deployment/src/main/java/io/quarkus/qute/deployment/QuteDevModeProcessor.java b/extensions/qute/deployment/src/main/java/io/quarkus/qute/deployment/QuteDevModeProcessor.java new file mode 100644 index 0000000000000..4baf3b0756616 --- /dev/null +++ b/extensions/qute/deployment/src/main/java/io/quarkus/qute/deployment/QuteDevModeProcessor.java @@ -0,0 +1,31 @@ +package io.quarkus.qute.deployment; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import io.quarkus.arc.deployment.ValidationPhaseBuildItem.ValidationErrorBuildItem; +import io.quarkus.deployment.IsDevelopment; +import io.quarkus.deployment.annotations.BuildProducer; +import io.quarkus.deployment.annotations.BuildStep; +import io.quarkus.deployment.annotations.BuildSteps; +import io.quarkus.dev.console.DevConsoleManager; +import io.quarkus.qute.runtime.devmode.QuteErrorPageSetup; + +@BuildSteps(onlyIf = IsDevelopment.class) +public class QuteDevModeProcessor { + + @BuildStep + void collectGeneratedContents(List templatePaths, + BuildProducer errors) { + Map contents = new HashMap<>(); + for (TemplatePathBuildItem template : templatePaths) { + if (!template.isFileBased()) { + contents.put(template.getPath(), template.getContent()); + } + } + // Set the global that could be used at runtime when a qute error page is rendered + DevConsoleManager.setGlobal(QuteErrorPageSetup.GENERATED_CONTENTS, contents); + } + +} diff --git a/extensions/qute/runtime/src/main/java/io/quarkus/qute/runtime/devmode/QuteErrorPageSetup.java b/extensions/qute/runtime/src/main/java/io/quarkus/qute/runtime/devmode/QuteErrorPageSetup.java index b7ced362defac..916522c98443f 100644 --- a/extensions/qute/runtime/src/main/java/io/quarkus/qute/runtime/devmode/QuteErrorPageSetup.java +++ b/extensions/qute/runtime/src/main/java/io/quarkus/qute/runtime/devmode/QuteErrorPageSetup.java @@ -2,6 +2,7 @@ import java.io.BufferedReader; import java.io.IOException; +import java.io.StringReader; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.nio.file.Files; @@ -12,6 +13,7 @@ import java.util.Comparator; import java.util.List; import java.util.ListIterator; +import java.util.Map; import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletionStage; import java.util.stream.Collectors; @@ -19,6 +21,7 @@ import org.jboss.logging.Logger; import io.quarkus.dev.ErrorPageGenerators; +import io.quarkus.dev.console.DevConsoleManager; import io.quarkus.dev.spi.HotReplacementContext; import io.quarkus.dev.spi.HotReplacementSetup; import io.quarkus.qute.Engine; @@ -33,6 +36,8 @@ public class QuteErrorPageSetup implements HotReplacementSetup { private static final Logger LOG = Logger.getLogger(QuteErrorPageSetup.class); + public static final String GENERATED_CONTENTS = "io.quarkus.qute.generatedContents"; + private static final String TEMPLATE_EXCEPTION = "io.quarkus.qute.TemplateException"; private static final String ORIGIN = "io.quarkus.qute.TemplateNode$Origin"; @@ -139,6 +144,10 @@ String getProblemInfo(int index, Throwable problem, Template problemTemplate, Es LOG.warn("Unable to read the template source: " + templateId, e); } + if (sourceLines.isEmpty()) { + return Arrays.stream(messageLines).collect(Collectors.joining("
")); + } + List realLines = new ArrayList<>(); boolean endLinesSkipped = false; if (sourceLines.size() > 15) { @@ -187,6 +196,14 @@ private BufferedReader getBufferedReader(String templateId) throws IOException { } } } + // Source file not available - try to search the generated contents + Map generatedContents = DevConsoleManager.getGlobal(GENERATED_CONTENTS); + if (generatedContents != null) { + String template = generatedContents.get(templateId); + if (template != null) { + return new BufferedReader(new StringReader(template)); + } + } throw new IllegalStateException("Template source not available"); }