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 <ahu...@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 ahu...@apache.org.