Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Permits to fix and reload broken extensions in dev systems. #880

Merged
merged 3 commits into from
Jul 5, 2021
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 27 additions & 15 deletions src/main/java/sirius/pasta/tagliatelle/Tagliatelle.java
Original file line number Diff line number Diff line change
Expand Up @@ -94,20 +94,32 @@ public MultiMap<String, String> getTagLibTags() {
*/
public List<TemplateExtension> getExtensions(String target) {
synchronized (extensions) {
List<TemplateExtension> result = extensions.get(target);
if (result == null) {
// As we might re-enter this method while compiling templates in "loadExtensions" we provide a
// placeholder value here to avoid infinite recursions. (Under normal circumstances, this shouldn't
// happen anyway, as cyclic extensions make no sense at all).
extensions.put(target, new ArrayList<>());

// Load and fill the result list. Note that we cannot use HashMap.computeIfAbsent here, as
// loadExtensions itself compiles templates which might end up calling this method leading
// to a ConcurrentModificationException...
result = loadExtensions(target);
extensions.put(target, result);
try {
List<TemplateExtension> result = extensions.get(target);
if (result == null) {
// As we might re-enter this method while compiling templates in "loadExtensions" we provide a
// placeholder value here to avoid infinite recursions. (Under normal circumstances, this shouldn't
// happen anyway, as cyclic extensions make no sense at all).
extensions.put(target, new ArrayList<>());

// Load and fill the result list. Note that we cannot use HashMap.computeIfAbsent here, as
// loadExtensions itself compiles templates which might end up calling this method leading
// to a ConcurrentModificationException...
result = loadExtensions(target);
extensions.put(target, result);
}
return Collections.unmodifiableList(result);
} catch (Exception exception) {
// If an error occurs while compiling the extensions, we remove our empty placeholder in debug
// environments, as it is very likely that the developer will fix the template and attempt to
// reload the page. If we didn't clear the extension, the page will simply show up empty.
// Note that if this happens in prod environments, we keep the empty list so that the same error
// only get reported once...
if (Sirius.isDev()) {
extensions.remove(target);
}
throw exception;
}
return Collections.unmodifiableList(result);
}
}

Expand All @@ -126,7 +138,7 @@ private List<TemplateExtension> loadExtensions(String target) {
private TemplateExtension resolveToTemplateExtension(String path) {
try {
Optional<Template> template = resolve("/" + path);
if (!template.isPresent()) {
if (template.isEmpty()) {
throw Exceptions.handle()
.to(Pasta.LOG)
.withSystemErrorMessage("Cannot resolve extension '%s' into a template!", path)
Expand Down Expand Up @@ -234,7 +246,7 @@ public Optional<Template> resolve(String path, @Nullable TemplateCompilationCont
throws CompileException {
ensureProperTemplatePath(path);
Optional<Resource> optionalResource = resources.resolve(path);
if (!optionalResource.isPresent()) {
if (optionalResource.isEmpty()) {
return Optional.empty();
}

Expand Down