You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@isis.apache.org by ah...@apache.org on 2018/06/15 13:30:25 UTC
[isis] branch master updated: ISIS-1963: workaround the issue by
selective exception suppression
This is an automated email from the ASF dual-hosted git repository.
ahuber pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/isis.git
The following commit(s) were added to refs/heads/master by this push:
new d7fefd3 ISIS-1963: workaround the issue by selective exception suppression
d7fefd3 is described below
commit d7fefd3edfcfb4c80032d46d29a132639db7bbd9
Author: Andi Huber <ah...@apache.org>
AuthorDate: Fri Jun 15 15:29:25 2018 +0200
ISIS-1963: workaround the issue by selective exception suppression
Task-Url: https://issues.apache.org/jira/browse/ISIS-1963
---
.../commons/internal/exceptions/_Exceptions.java | 149 +++++++++++++++++----
.../core/webapp/content/ResourceCachingFilter.java | 7 +-
.../wicket/ui/panels/PromptFormAbstract.java | 45 ++++---
3 files changed, 157 insertions(+), 44 deletions(-)
diff --git a/core/commons/src/main/java/org/apache/isis/commons/internal/exceptions/_Exceptions.java b/core/commons/src/main/java/org/apache/isis/commons/internal/exceptions/_Exceptions.java
index ceea19e..7200cc1 100644
--- a/core/commons/src/main/java/org/apache/isis/commons/internal/exceptions/_Exceptions.java
+++ b/core/commons/src/main/java/org/apache/isis/commons/internal/exceptions/_Exceptions.java
@@ -19,11 +19,15 @@
package org.apache.isis.commons.internal.exceptions;
+import static org.apache.isis.commons.internal.base._With.requires;
+
import java.util.Collections;
import java.util.List;
import java.util.Objects;
+import java.util.Optional;
import java.util.function.Consumer;
import java.util.function.Function;
+import java.util.function.Predicate;
import java.util.stream.Stream;
import javax.annotation.Nullable;
@@ -47,9 +51,9 @@ import org.apache.isis.commons.internal.functions._Functions;
public final class _Exceptions {
private _Exceptions(){}
-
+
// -- FRAMEWORK INTERNAL ERRORS
-
+
/**
* Most likely to be used in switch statements to handle the default case.
* @param _case the unmatched case to be reported
@@ -58,7 +62,7 @@ public final class _Exceptions {
public static final IllegalArgumentException unmatchedCase(@Nullable Object _case) {
return new IllegalArgumentException("internal error: unmatched case in switch statement: "+_case);
}
-
+
/**
* Most likely to be used in switch statements to handle the default case.
* @param format like in {@link java.lang.String#format(String, Object...)}
@@ -69,15 +73,15 @@ public final class _Exceptions {
Objects.requireNonNull(format);
return new IllegalArgumentException(String.format(format, _case));
}
-
+
public static final IllegalStateException unexpectedCodeReach() {
return new IllegalStateException("internal error: code was reached, that is expected unreachable");
}
-
+
public static IllegalStateException notImplemented() {
return new IllegalStateException("internal error: code was reached, that is not implemented yet");
}
-
+
/**
* Used to hide from the compiler the fact, that this call always throws.
*
@@ -98,10 +102,41 @@ public final class _Exceptions {
public static IllegalStateException throwNotImplemented() {
throw notImplemented();
}
+
+ // -- SELECTIVE ERROR SUPPRESSION
+
+// /**
+// * Allows to selectively ignore unchecked exceptions. Most likely used framework internally
+// * for workarounds, not properly dealing with the root cause. This way at least we know, where
+// * we placed such workarounds.
+// *
+// * @param runnable that might throw an unchecked exception
+// * @param suppress predicate that decides whether to suppress an exception
+// */
+// public static void catchSilently(
+// Runnable runnable,
+// Predicate<RuntimeException> suppress) {
+//
+// try {
+// runnable.run();
+// } catch (RuntimeException cause) {
+// if(suppress.test(cause)) {
+// return;
+// }
+// throw cause;
+// }
+// }
+ // -- SELECTIVE THROW
+ public static <E extends Exception> void throwWhenTrue(E cause, Predicate<E> test) throws E {
+ if(test.test(cause)) {
+ throw cause;
+ }
+ }
+
// -- STACKTRACE UTILITITIES
-
+
public static final Stream<String> streamStacktraceLines(@Nullable Throwable ex, int maxLines) {
if(ex==null) {
return Stream.empty();
@@ -110,7 +145,7 @@ public final class _Exceptions {
.map(StackTraceElement::toString)
.limit(maxLines);
}
-
+
// -- CAUSAL CHAIN
public static List<Throwable> getCausalChain(@Nullable Throwable ex) {
@@ -125,7 +160,7 @@ public final class _Exceptions {
}
return chain;
}
-
+
public static Stream<Throwable> streamCausalChain(@Nullable Throwable ex) {
if(ex==null) {
return Stream.empty();
@@ -137,48 +172,116 @@ public final class _Exceptions {
return _Lists.lastElementIfAny(getCausalChain(ex));
}
- // --
+ // -- FLUENT EXCEPTION
/**
+ * [ahuber] Experimental, remove if it adds no value. Otherwise expand.
+ */
+ public static class FluentException<E extends Exception> {
+
+ public static <E extends Exception> FluentException<E> of(E cause) {
+ return new FluentException<>(cause);
+ }
+
+ private final E cause;
+
+ private FluentException(E cause) {
+ requires(cause, "cause");
+ this.cause = cause;
+ }
+
+ public E getCause() {
+ return cause;
+ }
+
+ public Optional<String> getMessage() {
+ return Optional.ofNullable(cause.getMessage());
+ }
+
+ // -- RE-THROW IDIOMS
+
+ public void rethrow() throws E {
+ throw cause;
+ }
+
+ public void rethrowIf(Predicate<E> condition) throws E {
+ requires(condition, "condition");
+ if(condition.test(cause)) {
+ throw cause;
+ }
+ }
+
+ public void suppressIf(Predicate<E> condition) throws E {
+ requires(condition, "condition");
+ if(!condition.test(cause)) {
+ throw cause;
+ }
+ }
+
+ public void rethrowIfMessageContains(String string) throws E {
+ requires(string, "string");
+ final boolean containsMessage = getMessage().map(msg->msg.contains(string)).orElse(false);
+ if(containsMessage) {
+ throw cause;
+ }
+ }
+
+ public void suppressIfMessageContains(String string) throws E {
+ requires(string, "string");
+ final boolean containsMessage = getMessage().map(msg->msg.contains(string)).orElse(false);
+ if(!containsMessage) {
+ throw cause;
+ }
+ }
+
+ }
+
+ // --
+
+ /**
* [ahuber] Experimental, remove if it adds no value.
*/
public static class TryContext {
-
+
private final Function<Exception, ? extends RuntimeException> toUnchecked;
-
+
public TryContext(Function<Exception, ? extends RuntimeException> toUnchecked) {
this.toUnchecked = toUnchecked;
}
- // -- SHORTCUTS (RUNNABLE)
-
+ // -- SHORTCUTS (RUNNABLE)
+
public Runnable uncheckedRunnable(_Functions.CheckedRunnable checkedRunnable) {
return checkedRunnable.toUnchecked(toUnchecked);
}
-
+
public void tryRun(_Functions.CheckedRunnable checkedRunnable) {
uncheckedRunnable(checkedRunnable).run();
}
-
- // -- SHORTCUTS (FUNCTION)
-
+
+ // -- SHORTCUTS (FUNCTION)
+
public <T, R> Function<T, R> uncheckedFunction(_Functions.CheckedFunction<T, R> checkedFunction) {
return checkedFunction.toUnchecked(toUnchecked);
}
-
+
public <T, R> R tryApply(T obj, _Functions.CheckedFunction<T, R> checkedFunction) {
return uncheckedFunction(checkedFunction).apply(obj);
}
-
- // -- SHORTCUTS (CONSUMER)
+
+ // -- SHORTCUTS (CONSUMER)
public <T> Consumer<T> uncheckedConsumer(_Functions.CheckedConsumer<T> checkedConsumer) {
return checkedConsumer.toUnchecked(toUnchecked);
}
-
+
public <T> void tryAccept(T obj, _Functions.CheckedConsumer<T> checkedConsumer) {
uncheckedConsumer(checkedConsumer).accept(obj);
}
}
-
+
+
+
+
+
}
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/webapp/content/ResourceCachingFilter.java b/core/metamodel/src/main/java/org/apache/isis/core/webapp/content/ResourceCachingFilter.java
index 0d9c81d..893db9e 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/webapp/content/ResourceCachingFilter.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/webapp/content/ResourceCachingFilter.java
@@ -36,6 +36,8 @@ import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
+import org.apache.isis.commons.internal.exceptions._Exceptions.FluentException;
+
/**
* Adapted from {@link http
* ://www.digitalsanctuary.com/tech-blog/java/jboss/setting
@@ -235,9 +237,8 @@ public class ResourceCachingFilter implements Filter {
try {
chain.doFilter(servletRequest, servletResponse);
} catch (IOException e) {
- if(!isConnectionAbortException(e)) {
- throw e;
- }
+ FluentException.of(e)
+ .suppressIf(this::isConnectionAbortException);
}
}
diff --git a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/panels/PromptFormAbstract.java b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/panels/PromptFormAbstract.java
index bd9629e..6411b56 100644
--- a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/panels/PromptFormAbstract.java
+++ b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/panels/PromptFormAbstract.java
@@ -20,8 +20,22 @@ package org.apache.isis.viewer.wicket.ui.panels;
import java.util.List;
-import com.google.common.collect.Lists;
-
+import org.apache.isis.commons.internal.exceptions._Exceptions.FluentException;
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.viewer.wicket.model.hints.UiHintContainer;
+import org.apache.isis.viewer.wicket.model.isis.WicketViewerSettings;
+import org.apache.isis.viewer.wicket.model.models.ActionPrompt;
+import org.apache.isis.viewer.wicket.model.models.ActionPromptProvider;
+import org.apache.isis.viewer.wicket.model.models.BookmarkableModel;
+import org.apache.isis.viewer.wicket.model.models.FormExecutor;
+import org.apache.isis.viewer.wicket.model.models.FormExecutorContext;
+import org.apache.isis.viewer.wicket.model.models.ParentEntityModelProvider;
+import org.apache.isis.viewer.wicket.ui.components.scalars.ScalarModelSubscriber2;
+import org.apache.isis.viewer.wicket.ui.components.scalars.ScalarPanelAbstract2;
+import org.apache.isis.viewer.wicket.ui.components.widgets.formcomponent.FormFeedbackPanel;
+import org.apache.isis.viewer.wicket.ui.errors.JGrowlBehaviour;
+import org.apache.isis.viewer.wicket.ui.pages.PageAbstract;
+import org.apache.isis.viewer.wicket.ui.pages.entity.EntityPage;
import org.apache.wicket.Component;
import org.apache.wicket.MarkupContainer;
import org.apache.wicket.Page;
@@ -40,21 +54,7 @@ import org.apache.wicket.model.IModel;
import org.apache.wicket.model.ResourceModel;
import org.apache.wicket.util.string.AppendingStringBuffer;
-import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
-import org.apache.isis.viewer.wicket.model.hints.UiHintContainer;
-import org.apache.isis.viewer.wicket.model.isis.WicketViewerSettings;
-import org.apache.isis.viewer.wicket.model.models.ActionPrompt;
-import org.apache.isis.viewer.wicket.model.models.ActionPromptProvider;
-import org.apache.isis.viewer.wicket.model.models.BookmarkableModel;
-import org.apache.isis.viewer.wicket.model.models.FormExecutor;
-import org.apache.isis.viewer.wicket.model.models.FormExecutorContext;
-import org.apache.isis.viewer.wicket.model.models.ParentEntityModelProvider;
-import org.apache.isis.viewer.wicket.ui.components.scalars.ScalarModelSubscriber2;
-import org.apache.isis.viewer.wicket.ui.components.scalars.ScalarPanelAbstract2;
-import org.apache.isis.viewer.wicket.ui.components.widgets.formcomponent.FormFeedbackPanel;
-import org.apache.isis.viewer.wicket.ui.errors.JGrowlBehaviour;
-import org.apache.isis.viewer.wicket.ui.pages.PageAbstract;
-import org.apache.isis.viewer.wicket.ui.pages.entity.EntityPage;
+import com.google.common.collect.Lists;
public abstract class PromptFormAbstract<T extends BookmarkableModel<ObjectAdapter>
& ParentEntityModelProvider
@@ -236,7 +236,16 @@ public abstract class PromptFormAbstract<T extends BookmarkableModel<ObjectAdapt
completePrompt(target);
okButton.send(target.getPage(), Broadcast.EXACT, newCompletedEvent(target, form));
- target.add(form);
+ //TODO as of Wicket-8 we (for lack of a better solution) silently ignore java.lang.IllegalArgumentException:
+ // 'Cannot update component because its page is not the same as the one this handler has been created for.'
+
+ try {
+ target.add(form);
+ } catch (IllegalArgumentException cause) {
+ FluentException.of(cause)
+ .suppressIfMessageContains("Cannot update component because its page is not the same");
+ }
+
}
}
--
To stop receiving notification emails like this one, please contact
ahuber@apache.org.