You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by lo...@apache.org on 2018/11/01 09:04:59 UTC
[myfaces-tobago] branch master updated: TOBAGO-1946: Better
ExceptionHandling for applications
This is an automated email from the ASF dual-hosted git repository.
lofwyr pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/myfaces-tobago.git
The following commit(s) were added to refs/heads/master by this push:
new b98f7b9 TOBAGO-1946: Better ExceptionHandling for applications
b98f7b9 is described below
commit b98f7b9e5e09360b67cabda206ef4f5f4a84d591
Author: Udo Schnurpfeil <lo...@apache.org>
AuthorDate: Thu Nov 1 10:03:45 2018 +0100
TOBAGO-1946: Better ExceptionHandling for applications
---
.../tobago/context/TobagoExceptionHandler.java | 129 +++++++++++++++++++++
.../context/TobagoExceptionHandlerFactory.java | 19 ++-
.../META-INF/resources/tobago/error.xhtml | 28 +++++
.../tobago/example/demo/TestExceptionHandler.java | 87 --------------
.../src/main/webapp/WEB-INF/faces-config.xml | 2 +-
.../src/main/webapp/WEB-INF/web.xml | 2 +-
6 files changed, 174 insertions(+), 93 deletions(-)
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/context/TobagoExceptionHandler.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/context/TobagoExceptionHandler.java
new file mode 100644
index 0000000..67094f4
--- /dev/null
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/context/TobagoExceptionHandler.java
@@ -0,0 +1,129 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.myfaces.tobago.context;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.faces.FacesException;
+import javax.faces.application.FacesMessage;
+import javax.faces.application.NavigationHandler;
+import javax.faces.application.ViewExpiredException;
+import javax.faces.application.ViewHandler;
+import javax.faces.component.UIViewRoot;
+import javax.faces.context.ExceptionHandler;
+import javax.faces.context.ExceptionHandlerWrapper;
+import javax.faces.context.FacesContext;
+import javax.faces.event.ExceptionQueuedEvent;
+import javax.faces.event.ExceptionQueuedEventContext;
+import javax.faces.event.PhaseId;
+import javax.faces.event.PreRenderViewEvent;
+import javax.faces.view.ViewDeclarationLanguage;
+import javax.servlet.http.HttpServletResponse;
+import java.io.FileNotFoundException;
+import java.util.Iterator;
+
+public class TobagoExceptionHandler extends ExceptionHandlerWrapper {
+
+ private static final Logger LOG = LoggerFactory.getLogger(TobagoExceptionHandler.class);
+
+ private ExceptionHandler wrapped;
+
+ public TobagoExceptionHandler(final ExceptionHandler wrapped) {
+ this.wrapped = wrapped;
+ }
+
+ @Override
+ public ExceptionHandler getWrapped() {
+ return wrapped;
+ }
+
+ @Override
+ public void handle() throws FacesException {
+
+ final Iterator<ExceptionQueuedEvent> iterator = getUnhandledExceptionQueuedEvents().iterator();
+ while (iterator.hasNext()) {
+ final ExceptionQueuedEvent event = iterator.next();
+ final ExceptionQueuedEventContext context = (ExceptionQueuedEventContext) event.getSource();
+ final Throwable cause = this.getWrapped().getRootCause(context.getException());
+ final FacesContext facesContext = FacesContext.getCurrentInstance();
+ final NavigationHandler nav = facesContext.getApplication().getNavigationHandler();
+
+ if (cause instanceof ViewExpiredException
+ || cause != null && cause.getCause() instanceof ViewExpiredException) {
+ final ViewExpiredException viewExpiredException = (ViewExpiredException)
+ (cause instanceof ViewExpiredException ? cause : cause.getCause());
+ try {
+ facesContext.addMessage(null,
+ new FacesMessage(FacesMessage.SEVERITY_WARN,
+ "The view has been expired!",
+ "Please check the given data or try to start from the beginning."));
+ nav.handleNavigation(facesContext, null, viewExpiredException.getViewId());
+ facesContext.renderResponse();
+ LOG.debug("Handling ViewExpiredException on viewId: {}", viewExpiredException.getViewId());
+ } finally {
+ iterator.remove();
+ }
+ } else {
+ try {
+ final boolean error404 = cause instanceof FileNotFoundException
+ || cause != null && cause.getCause() instanceof FileNotFoundException;
+ final FacesMessage message;
+ if (error404) {
+ message = new FacesMessage(FacesMessage.SEVERITY_ERROR,
+ "The page was not found!",
+ "The requested page was not found!");
+ facesContext.getExternalContext().setResponseStatus(HttpServletResponse.SC_NOT_FOUND);
+ LOG.warn("Handling 404 exception.");
+ } else {
+ message = new FacesMessage(FacesMessage.SEVERITY_ERROR,
+ "An unknown error has occurred!",
+ "An unknown error has occurred!");
+ facesContext.getExternalContext().setResponseStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
+ LOG.warn("Handling 500 exception.", cause);
+ }
+ facesContext.addMessage(null, message);
+ final String viewId = "/tobago/error.xhtml";
+
+ // when the rendering was not yet started, we can forward to an error page
+ if (event.getContext().getPhaseId().getOrdinal() < PhaseId.RENDER_RESPONSE.getOrdinal()) {
+ nav.handleNavigation(facesContext, null, viewId);
+ facesContext.renderResponse();
+ } else {
+ final HttpServletResponse response = (HttpServletResponse) facesContext.getExternalContext().getResponse();
+ response.resetBuffer(); // undo rendering, if you can.
+ final ViewHandler viewHandler = facesContext.getApplication().getViewHandler();
+ final ViewDeclarationLanguage vdl = viewHandler.getViewDeclarationLanguage(facesContext, viewId);
+ final UIViewRoot viewRoot = viewHandler.createView(facesContext, viewId);
+ vdl.buildView(facesContext, viewRoot);
+ facesContext.getApplication().publishEvent(facesContext, PreRenderViewEvent.class, viewRoot);
+ vdl.renderView(facesContext, viewRoot);
+ facesContext.responseComplete();
+ }
+ } catch (Exception e) {
+ LOG.error("Exception while exception handling!", e);
+ } finally {
+ iterator.remove();
+ }
+ }
+ }
+ getWrapped().handle();
+ }
+}
diff --git a/tobago-example/tobago-example-demo/src/main/java/org/apache/myfaces/tobago/example/demo/TestExceptionHandlerFactory.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/context/TobagoExceptionHandlerFactory.java
similarity index 66%
rename from tobago-example/tobago-example-demo/src/main/java/org/apache/myfaces/tobago/example/demo/TestExceptionHandlerFactory.java
rename to tobago-core/src/main/java/org/apache/myfaces/tobago/context/TobagoExceptionHandlerFactory.java
index a6cb346..a97c0d2 100644
--- a/tobago-example/tobago-example-demo/src/main/java/org/apache/myfaces/tobago/example/demo/TestExceptionHandlerFactory.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/context/TobagoExceptionHandlerFactory.java
@@ -17,23 +17,34 @@
* under the License.
*/
-package org.apache.myfaces.tobago.example.demo;
+package org.apache.myfaces.tobago.context;
import javax.faces.context.ExceptionHandler;
import javax.faces.context.ExceptionHandlerFactory;
-public class TestExceptionHandlerFactory extends ExceptionHandlerFactory {
+/**
+ * To enable the TobagoExceptionHandler insert this class in the faces-config.xml like:
+ * <pre>
+ * <factory>
+ * <exception-handler-factory>
+ * org.apache.myfaces.tobago.example.demo.TobagoExceptionHandlerFactory
+ * </exception-handler-factory>
+ * </factory>
+ * </pre>
+ *
+ */
+public class TobagoExceptionHandlerFactory extends ExceptionHandlerFactory {
private ExceptionHandlerFactory parent;
- public TestExceptionHandlerFactory(final ExceptionHandlerFactory parent) {
+ public TobagoExceptionHandlerFactory(final ExceptionHandlerFactory parent) {
this.parent = parent;
}
@Override
public ExceptionHandler getExceptionHandler() {
ExceptionHandler result = parent.getExceptionHandler();
- result = new TestExceptionHandler(result);
+ result = new TobagoExceptionHandler(result);
return result;
}
diff --git a/tobago-core/src/main/resources/META-INF/resources/tobago/error.xhtml b/tobago-core/src/main/resources/META-INF/resources/tobago/error.xhtml
new file mode 100644
index 0000000..1946dd5
--- /dev/null
+++ b/tobago-core/src/main/resources/META-INF/resources/tobago/error.xhtml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+-->
+
+<f:view xmlns:f="http://java.sun.com/jsf/core"
+ xmlns:tc="http://myfaces.apache.org/tobago/component">
+
+ <tc:page>
+ <tc:messages/>
+ </tc:page>
+
+</f:view>
+
diff --git a/tobago-example/tobago-example-demo/src/main/java/org/apache/myfaces/tobago/example/demo/TestExceptionHandler.java b/tobago-example/tobago-example-demo/src/main/java/org/apache/myfaces/tobago/example/demo/TestExceptionHandler.java
deleted file mode 100644
index ab208c5..0000000
--- a/tobago-example/tobago-example-demo/src/main/java/org/apache/myfaces/tobago/example/demo/TestExceptionHandler.java
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.apache.myfaces.tobago.example.demo;
-
-import javax.faces.FacesException;
-import javax.faces.application.FacesMessage;
-import javax.faces.application.NavigationHandler;
-import javax.faces.application.ViewExpiredException;
-import javax.faces.context.ExceptionHandler;
-import javax.faces.context.ExceptionHandlerWrapper;
-import javax.faces.context.FacesContext;
-import javax.faces.event.ExceptionQueuedEvent;
-import javax.faces.event.ExceptionQueuedEventContext;
-import javax.servlet.http.HttpServletResponse;
-import java.io.FileNotFoundException;
-import java.util.Iterator;
-
-public class TestExceptionHandler extends ExceptionHandlerWrapper {
-
- private ExceptionHandler wrapped;
-
- public TestExceptionHandler(final ExceptionHandler wrapped) {
- this.wrapped = wrapped;
- }
-
- @Override
- public ExceptionHandler getWrapped() {
- return wrapped;
- }
-
- @Override
- public void handle() throws FacesException {
-
- final Iterator<ExceptionQueuedEvent> iterator = getUnhandledExceptionQueuedEvents().iterator();
- while (iterator.hasNext()) {
- final ExceptionQueuedEvent event = iterator.next();
- final ExceptionQueuedEventContext context = (ExceptionQueuedEventContext) event.getSource();
- final Throwable cause = context.getException();
-
- if (cause instanceof ViewExpiredException) {
- final FacesContext facesContext = FacesContext.getCurrentInstance();
- final NavigationHandler nav = facesContext.getApplication().getNavigationHandler();
- try {
- facesContext.addMessage(null, new FacesMessage("The view has been expired!"));
-
- /*
- * TODO analyse the '/faces'-prefix
- * actually the viewID should be enough, but if you do so, the FacesMessage won't be shown.
- */
- nav.handleNavigation(facesContext, null, ((ViewExpiredException) cause).getViewId());
- facesContext.renderResponse();
- } finally {
- iterator.remove();
- }
- } else if (cause instanceof FileNotFoundException
- || cause != null && cause.getCause() instanceof FileNotFoundException) {
- try {
- final FacesContext facesContext = FacesContext.getCurrentInstance();
- final NavigationHandler nav = facesContext.getApplication().getNavigationHandler();
- nav.handleNavigation(facesContext, null, "/error/404.xhtml");
- facesContext.getExternalContext().setResponseStatus(HttpServletResponse.SC_NOT_FOUND);
- facesContext.renderResponse();
- } finally {
- iterator.remove();
- }
- }
- }
- getWrapped().handle();
- }
-}
diff --git a/tobago-example/tobago-example-demo/src/main/webapp/WEB-INF/faces-config.xml b/tobago-example/tobago-example-demo/src/main/webapp/WEB-INF/faces-config.xml
index fff55cb..f291fda 100644
--- a/tobago-example/tobago-example-demo/src/main/webapp/WEB-INF/faces-config.xml
+++ b/tobago-example/tobago-example-demo/src/main/webapp/WEB-INF/faces-config.xml
@@ -58,7 +58,7 @@
<factory>
<exception-handler-factory>
- org.apache.myfaces.tobago.example.demo.TestExceptionHandlerFactory
+ org.apache.myfaces.tobago.context.TobagoExceptionHandlerFactory
</exception-handler-factory>
</factory>
diff --git a/tobago-example/tobago-example-demo/src/main/webapp/WEB-INF/web.xml b/tobago-example/tobago-example-demo/src/main/webapp/WEB-INF/web.xml
index 09bcad8..8ac66da 100644
--- a/tobago-example/tobago-example-demo/src/main/webapp/WEB-INF/web.xml
+++ b/tobago-example/tobago-example-demo/src/main/webapp/WEB-INF/web.xml
@@ -148,7 +148,7 @@
</servlet-mapping>
<!-- Error handling, see also these classes:
- org.apache.myfaces.tobago.example.demo.TestExceptionHandler
+ org.apache.myfaces.tobago.example.demo.TobagoExceptionHandler
org.apache.myfaces.tobago.example.demo.DeltaSpikeClientWindowConfig
-->