You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by lu...@apache.org on 2011/06/30 01:22:31 UTC
svn commit: r1141325 - in
/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces: application/
context/ lifecycle/ renderkit/
Author: lu4242
Date: Wed Jun 29 23:22:30 2011
New Revision: 1141325
URL: http://svn.apache.org/viewvc?rev=1141325&view=rev
Log:
MYFACES-3053 Improve error reporting and logging (fix Ajax case, add MyFacesExceptionHandlerWrapperImpl, output multiple exception stack traces, disable MyFaces exception handling if Project Stage is not Development)
Added:
myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/context/MyFacesExceptionHandlerWrapperImpl.java
Modified:
myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/ResourceHandlerImpl.java
myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/context/ExceptionHandlerFactoryImpl.java
myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/lifecycle/LifecycleImpl.java
myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/renderkit/ErrorPageWriter.java
Modified: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/ResourceHandlerImpl.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/ResourceHandlerImpl.java?rev=1141325&r1=1141324&r2=1141325&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/ResourceHandlerImpl.java (original)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/ResourceHandlerImpl.java Wed Jun 29 23:22:30 2011
@@ -259,8 +259,8 @@ public class ResourceHandlerImpl extends
@Override
public void handleResourceRequest(FacesContext facesContext) throws IOException
{
- try
- {
+ //try
+ //{
String resourceBasePath = getResourceHandlerSupport()
.calculateResourceBasePath(facesContext);
@@ -373,14 +373,14 @@ public class ResourceHandlerImpl extends
+ e.getMessage());
httpServletResponse.setStatus(HttpServletResponse.SC_NOT_FOUND);
}
- }
- catch (Throwable ex)
- {
+ //}
+ //catch (Throwable ex)
+ //{
// handle the Throwable accordingly. Maybe generate an error page.
// FIXME we are creating a html error page for a non html request here
// shouln't we do something better? -=Jakob Korherr=-
- ErrorPageWriter.handleThrowable(facesContext, ex);
- }
+ //ErrorPageWriter.handleThrowable(facesContext, ex);
+ //}
}
/**
Modified: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/context/ExceptionHandlerFactoryImpl.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/context/ExceptionHandlerFactoryImpl.java?rev=1141325&r1=1141324&r2=1141325&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/context/ExceptionHandlerFactoryImpl.java (original)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/context/ExceptionHandlerFactoryImpl.java Wed Jun 29 23:22:30 2011
@@ -21,7 +21,9 @@ package org.apache.myfaces.context;
import javax.faces.context.ExceptionHandler;
import javax.faces.context.ExceptionHandlerFactory;
+import org.apache.myfaces.shared_impl.context.AjaxExceptionHandlerImpl;
import org.apache.myfaces.shared_impl.context.ExceptionHandlerImpl;
+import org.apache.myfaces.shared_impl.context.SwitchAjaxExceptionHandlerWrapperImpl;
/**
* DOCUMENT ME!
@@ -37,6 +39,8 @@ public class ExceptionHandlerFactoryImpl
@Override
public ExceptionHandler getExceptionHandler()
{
- return new ExceptionHandlerImpl();
+ return new SwitchAjaxExceptionHandlerWrapperImpl(
+ new MyFacesExceptionHandlerWrapperImpl(new ExceptionHandlerImpl()) ,
+ new AjaxExceptionHandlerImpl());
}
}
Added: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/context/MyFacesExceptionHandlerWrapperImpl.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/context/MyFacesExceptionHandlerWrapperImpl.java?rev=1141325&view=auto
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/context/MyFacesExceptionHandlerWrapperImpl.java (added)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/context/MyFacesExceptionHandlerWrapperImpl.java Wed Jun 29 23:22:30 2011
@@ -0,0 +1,344 @@
+/*
+ * 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.context;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Queue;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.faces.FacesException;
+import javax.faces.application.ProjectStage;
+import javax.faces.context.ExceptionHandler;
+import javax.faces.context.ExceptionHandlerWrapper;
+import javax.faces.context.FacesContext;
+import javax.faces.event.AbortProcessingException;
+import javax.faces.event.ExceptionQueuedEvent;
+import javax.faces.event.ExceptionQueuedEventContext;
+import javax.faces.event.SystemEvent;
+
+import org.apache.myfaces.renderkit.ErrorPageWriter;
+import org.apache.myfaces.shared_impl.util.WebConfigParamUtils;
+import org.apache.myfaces.spi.WebConfigProvider;
+import org.apache.myfaces.spi.WebConfigProviderFactory;
+
+/**
+ * Extended MyFaces-specific ExceptionHandler implementation.
+ *
+ * @author Leonardo Uribe
+ *
+ */
+public class MyFacesExceptionHandlerWrapperImpl extends ExceptionHandlerWrapper
+{
+ private static final Logger log = Logger.getLogger(MyFacesExceptionHandlerWrapperImpl.class.getName());
+
+ private Queue<ExceptionQueuedEvent> handled;
+ private Queue<ExceptionQueuedEvent> unhandled;
+ private ExceptionQueuedEvent handledAndThrown;
+
+
+ private ExceptionHandler _delegate;
+ private boolean _isErrorPagePresent;
+ private boolean _useMyFacesErrorHandling;
+ private boolean _inited;
+
+ public MyFacesExceptionHandlerWrapperImpl(ExceptionHandler delegate)
+ {
+ this._delegate = delegate;
+ this._inited = false;
+ }
+
+ protected void init()
+ {
+ if (!_inited)
+ {
+ FacesContext facesContext = FacesContext.getCurrentInstance();
+ WebConfigProvider webConfigProvider = WebConfigProviderFactory.getWebConfigProviderFactory(
+ facesContext.getExternalContext()).getWebConfigProvider(facesContext.getExternalContext());
+
+ _isErrorPagePresent = webConfigProvider.isErrorPagePresent(facesContext.getExternalContext());
+ _useMyFacesErrorHandling = WebConfigParamUtils.getBooleanInitParameter(facesContext.getExternalContext(),
+ ErrorPageWriter.ERROR_HANDLING_PARAMETER, true);
+ _inited = true;
+ }
+ }
+
+ protected void init(FacesContext facesContext)
+ {
+ if (!_inited)
+ {
+ if (facesContext == null)
+ {
+ facesContext = FacesContext.getCurrentInstance();
+ }
+ WebConfigProvider webConfigProvider = WebConfigProviderFactory.getWebConfigProviderFactory(
+ facesContext.getExternalContext()).getWebConfigProvider(facesContext.getExternalContext());
+
+ _isErrorPagePresent = webConfigProvider.isErrorPagePresent(facesContext.getExternalContext());
+ _useMyFacesErrorHandling = WebConfigParamUtils.getBooleanInitParameter(facesContext.getExternalContext(),
+ ErrorPageWriter.ERROR_HANDLING_PARAMETER, facesContext.isProjectStage(ProjectStage.Development) ? true : false);
+ _inited = true;
+ }
+ }
+
+ protected void init(SystemEvent exceptionQueuedEvent)
+ {
+ if (!_inited)
+ {
+ if (exceptionQueuedEvent instanceof ExceptionQueuedEvent)
+ {
+ ExceptionQueuedEvent eqe = (ExceptionQueuedEvent)exceptionQueuedEvent;
+ ExceptionQueuedEventContext eqec = eqe.getContext();
+ if (eqec != null)
+ {
+ FacesContext facesContext = eqec.getContext();
+ if (facesContext != null)
+ {
+ init(facesContext);
+ return;
+ }
+ }
+ }
+ init(FacesContext.getCurrentInstance());
+ }
+ }
+
+ protected boolean isUseMyFacesErrorHandling()
+ {
+ return _useMyFacesErrorHandling;
+ }
+
+ protected boolean isErrorPagePresent()
+ {
+ return _isErrorPagePresent;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public ExceptionQueuedEvent getHandledExceptionQueuedEvent()
+ {
+ init();
+ if (!isUseMyFacesErrorHandling())
+ {
+ return super.getHandledExceptionQueuedEvent();
+ }
+ else
+ {
+ return handledAndThrown;
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Iterable<ExceptionQueuedEvent> getHandledExceptionQueuedEvents()
+ {
+ init();
+ if (!isUseMyFacesErrorHandling())
+ {
+ return super.getHandledExceptionQueuedEvents();
+ }
+ else
+ {
+ return handled == null ? Collections.<ExceptionQueuedEvent>emptyList() : handled;
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Iterable<ExceptionQueuedEvent> getUnhandledExceptionQueuedEvents()
+ {
+ init();
+ if (!isUseMyFacesErrorHandling())
+ {
+ return super.getUnhandledExceptionQueuedEvents();
+ }
+ else
+ {
+ return unhandled == null ? Collections.<ExceptionQueuedEvent>emptyList() : unhandled;
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void handle() throws FacesException
+ {
+ init();
+ if (!isUseMyFacesErrorHandling())
+ {
+ if (isErrorPagePresent())
+ {
+ FacesContext facesContext = FacesContext.getCurrentInstance();
+ // save current view in the request map to access it on the error page
+ facesContext.getExternalContext().getRequestMap().put(ErrorPageWriter.VIEW_KEY, facesContext.getViewRoot());
+ }
+ super.handle();
+ return;
+ }
+ else
+ {
+ if (unhandled != null && !unhandled.isEmpty())
+ {
+ if (handled == null)
+ {
+ handled = new LinkedList<ExceptionQueuedEvent>();
+ }
+
+ List<Throwable> throwableList = new ArrayList<Throwable>();
+ FacesContext facesContext = null;
+
+ do
+ {
+ // For each ExceptionEvent in the list
+
+ // get the event to handle
+ ExceptionQueuedEvent event = unhandled.peek();
+ try
+ {
+ // call its getContext() method
+ ExceptionQueuedEventContext context = event.getContext();
+
+ if (facesContext == null)
+ {
+ facesContext = event.getContext().getContext();
+ }
+
+ // and call getException() on the returned result
+ Throwable exception = context.getException();
+
+ // Upon encountering the first such Exception that is not an instance of
+ // javax.faces.event.AbortProcessingException
+ if (!shouldSkip(exception))
+ {
+ // set handledAndThrown so that getHandledExceptionQueuedEvent() returns this event
+ handledAndThrown = event;
+
+ Throwable rootCause = getRootCause(exception);
+
+ throwableList.add(rootCause == null ? exception : rootCause);
+
+ //break;
+ }
+ else
+ {
+ // Testing mojarra it logs a message and the exception
+ // however, this behaviour is not mentioned in the spec
+ log.log(Level.SEVERE, exception.getClass().getName() + " occured while processing " +
+ (context.inBeforePhase() ? "beforePhase() of " :
+ (context.inAfterPhase() ? "afterPhase() of " : "")) +
+ "phase " + context.getPhaseId() + ": " +
+ "UIComponent-ClientId=" +
+ (context.getComponent() != null ?
+ context.getComponent().getClientId(context.getContext()) : "") + ", " +
+ "Message=" + exception.getMessage());
+
+ log.log(Level.SEVERE, exception.getMessage(), exception);
+ }
+ }
+ finally
+ {
+ // if we will throw the Exception or if we just logged it,
+ // we handled it in either way --> add to handled
+ handled.add(event);
+ unhandled.remove(event);
+ }
+ } while (!unhandled.isEmpty());
+
+ if (facesContext == null)
+ {
+ facesContext = FacesContext.getCurrentInstance();
+ }
+ if (throwableList.size() == 1)
+ {
+ ErrorPageWriter.handle(facesContext, throwableList.get(0));
+ }
+ else
+ {
+ ErrorPageWriter.handle(facesContext, throwableList.toArray(new Throwable[throwableList.size()]));
+ }
+ }
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void processEvent(SystemEvent exceptionQueuedEvent) throws AbortProcessingException
+ {
+ init(exceptionQueuedEvent);
+
+ if (!isUseMyFacesErrorHandling())
+ {
+ super.processEvent(exceptionQueuedEvent);
+ }
+ else
+ {
+ if (unhandled == null)
+ {
+ unhandled = new LinkedList<ExceptionQueuedEvent>();
+ }
+
+ unhandled.add((ExceptionQueuedEvent)exceptionQueuedEvent);
+ }
+ }
+
+ protected Throwable getRethrownException(Throwable exception)
+ {
+ // Let toRethrow be either the result of calling getRootCause() on the Exception,
+ // or the Exception itself, whichever is non-null
+ Throwable toRethrow = getRootCause(exception);
+ if (toRethrow == null)
+ {
+ toRethrow = exception;
+ }
+
+ return toRethrow;
+ }
+
+ protected FacesException wrap(Throwable exception)
+ {
+ if (exception instanceof FacesException)
+ {
+ return (FacesException) exception;
+ }
+ return new FacesException(exception);
+ }
+
+ protected boolean shouldSkip(Throwable exception)
+ {
+ return exception instanceof AbortProcessingException;
+ }
+
+ @Override
+ public ExceptionHandler getWrapped()
+ {
+ return _delegate;
+ }
+}
Modified: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/lifecycle/LifecycleImpl.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/lifecycle/LifecycleImpl.java?rev=1141325&r1=1141324&r2=1141325&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/lifecycle/LifecycleImpl.java (original)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/lifecycle/LifecycleImpl.java Wed Jun 29 23:22:30 2011
@@ -102,8 +102,8 @@ public class LifecycleImpl extends Lifec
@Override
public void execute(FacesContext facesContext) throws FacesException
{
- try
- {
+ //try
+ //{
// check for updates of web.xml and faces-config descriptors
// only if project state is not production
if(!facesContext.isProjectStage(ProjectStage.Production))
@@ -120,12 +120,12 @@ public class LifecycleImpl extends Lifec
return;
}
}
- }
- catch (Throwable ex)
- {
+ //}
+ //catch (Throwable ex)
+ //{
// handle the Throwable accordingly. Maybe generate an error page.
- ErrorPageWriter.handleThrowable(facesContext, ex);
- }
+ //ErrorPageWriter.handleThrowable(facesContext, ex);
+ //}
}
private boolean executePhase(FacesContext context, PhaseExecutor executor, PhaseListenerManager phaseListenerMgr)
@@ -207,8 +207,8 @@ public class LifecycleImpl extends Lifec
@Override
public void render(FacesContext facesContext) throws FacesException
{
- try
- {
+ //try
+ //{
// if the response is complete we should not be invoking the phase listeners
if (isResponseComplete(facesContext, renderExecutor.getPhase(), true))
{
@@ -267,12 +267,12 @@ public class LifecycleImpl extends Lifec
{
log.finest("exiting " + renderExecutor.getPhase() + " in " + LifecycleImpl.class.getName());
}
- }
- catch (Throwable ex)
- {
+ //}
+ //catch (Throwable ex)
+ //{
// handle the Throwable accordingly. Maybe generate an error page.
- ErrorPageWriter.handleThrowable(facesContext, ex);
- }
+ //ErrorPageWriter.handleThrowable(facesContext, ex);
+ //}
}
private boolean isResponseComplete(FacesContext facesContext, PhaseId phase, boolean before)
Modified: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/renderkit/ErrorPageWriter.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/renderkit/ErrorPageWriter.java?rev=1141325&r1=1141324&r2=1141325&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/renderkit/ErrorPageWriter.java (original)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/renderkit/ErrorPageWriter.java Wed Jun 29 23:22:30 2011
@@ -72,7 +72,6 @@ import org.apache.myfaces.buildtools.mav
import org.apache.myfaces.shared_impl.renderkit.html.HtmlResponseWriterImpl;
import org.apache.myfaces.shared_impl.util.ClassUtils;
import org.apache.myfaces.shared_impl.util.StateUtils;
-import org.apache.myfaces.shared_impl.webapp.webxml.WebXml;
import org.apache.myfaces.spi.WebConfigProvider;
import org.apache.myfaces.spi.WebConfigProviderFactory;
import org.apache.myfaces.view.facelets.component.UIRepeat;
@@ -115,7 +114,7 @@ public final class ErrorPageWriter
UIViewRoot view = (UIViewRoot) requestMap.get(VIEW_KEY);
StringWriter writer = new StringWriter();
- ErrorPageWriter.debugHtml(writer, facesContext, t, view);
+ ErrorPageWriter.debugHtml(writer, facesContext, view, t);
String html = writer.toString();
// change the HTML in the buffer to be included in an existing html page
@@ -187,7 +186,7 @@ public final class ErrorPageWriter
public static final String ERROR_PAGE_BEAN_KEY = "__myFacesErrorPageBean";
private static final String EXCEPTION_KEY = "javax.servlet.error.exception";
- private static final String VIEW_KEY = "org.apache.myfaces.error.UIViewRoot";
+ public static final String VIEW_KEY = "org.apache.myfaces.error.UIViewRoot";
private static final Logger log = Logger.getLogger(ErrorPageWriter.class.getName());
@@ -229,9 +228,9 @@ public final class ErrorPageWriter
/**
* Indicate if myfaces is responsible to handle errors.
- * See http://wiki.apache.org/myfaces/Handling_Server_Errors for details.
+ * See http://wiki.apache.org/myfaces/Handling_Server_Errors for details.
*/
- @JSFWebConfigParam(defaultValue="true",expectedValues="true,false", since="1.2.4")
+ @JSFWebConfigParam(defaultValue="false, on Development Project stage: true",expectedValues="true,false", since="1.2.4")
public static final String ERROR_HANDLING_PARAMETER = "org.apache.myfaces.ERROR_HANDLING";
public ErrorPageWriter()
@@ -249,9 +248,10 @@ public final class ErrorPageWriter
*/
public static void debugHtml(Writer writer, FacesContext faces, Throwable e) throws IOException
{
- debugHtml(writer, faces, e, faces.getViewRoot());
+ debugHtml(writer, faces, faces.getViewRoot(), e);
}
+ /*
private static void debugHtml(Writer writer, FacesContext faces, Throwable e, UIViewRoot view) throws IOException
{
_init(faces);
@@ -298,6 +298,81 @@ public final class ErrorPageWriter
writer.write(ERROR_PARTS[i]);
}
}
+ }*/
+
+ private static void debugHtml(Writer writer, FacesContext faces, UIViewRoot view, Throwable... exs) throws IOException
+ {
+ _init(faces);
+ Date now = new Date();
+ for (int i = 0; i < ERROR_PARTS.length; i++)
+ {
+ if ("message".equals(ERROR_PARTS[i]))
+ {
+ boolean printed = false;
+ for (Throwable e : exs)
+ {
+ String msg = e.getMessage();
+ if (printed)
+ {
+ writer.write("<br/>");
+ }
+ if (msg != null)
+ {
+ writer.write(msg.replaceAll("<", TS));
+ }
+ else
+ {
+ writer.write(e.getClass().getName());
+ }
+ printed = true;
+ }
+ }
+ else if ("trace".equals(ERROR_PARTS[i]))
+ {
+ boolean printed = false;
+ for (Throwable e : exs)
+ {
+ if (printed)
+ {
+ writer.write("\n");
+ }
+ _writeException(writer, e);
+ printed = true;
+ }
+ }
+ else if ("now".equals(ERROR_PARTS[i]))
+ {
+ writer.write(DateFormat.getDateTimeInstance().format(now));
+ }
+ else if ("tree".equals(ERROR_PARTS[i]))
+ {
+ if (view != null)
+ {
+ _writeComponent(faces, writer, view, _getErrorId(exs));
+ }
+ }
+ else if ("vars".equals(ERROR_PARTS[i]))
+ {
+ _writeVariables(writer, faces, view);
+ }
+ else if ("cause".equals(ERROR_PARTS[i]))
+ {
+ boolean printed = false;
+ for (Throwable e : exs)
+ {
+ if (printed)
+ {
+ writer.write("<br/>");
+ }
+ _writeCause(writer, e);
+ printed = true;
+ }
+ }
+ else
+ {
+ writer.write(ERROR_PARTS[i]);
+ }
+ }
}
/**
@@ -339,6 +414,37 @@ public final class ErrorPageWriter
}
}
}
+
+ public static void handle(FacesContext facesContext, Throwable... exs) throws FacesException
+ {
+ for (Throwable ex : exs)
+ {
+ _prepareExceptionStack(ex);
+ }
+
+ if (!facesContext.getExternalContext().isResponseCommitted())
+ {
+ facesContext.getExternalContext().responseReset();
+ }
+
+ // normal request --> html error page
+ facesContext.getExternalContext().setResponseContentType("text/html");
+ facesContext.getExternalContext().setResponseCharacterEncoding("UTF-8");
+ try
+ {
+ // We need the real one, because the one returned from FacesContext.getResponseWriter()
+ // is configured with the encoding of the view.
+ Writer writer = facesContext.getExternalContext().getResponseOutputWriter();
+ debugHtml(writer, facesContext, facesContext.getViewRoot(), exs);
+ }
+ catch(IOException ioe)
+ {
+ throw new FacesException("Could not write the error page", ioe);
+ }
+
+ // mark the response as complete
+ facesContext.responseComplete();
+ }
/**
* Handles the given Throwbale in the following way:
@@ -350,7 +456,9 @@ public final class ErrorPageWriter
* @param facesContext
* @param ex
* @throws FacesException
+ * @deprecated Use MyFacesExceptionHandlerWrapperImpl and handle() method
*/
+ @Deprecated
public static void handleThrowable(FacesContext facesContext, Throwable ex) throws FacesException
{
_prepareExceptionStack(ex);
@@ -520,23 +628,32 @@ public final class ErrorPageWriter
return str.split("@@");
}
- private static List<String> _getErrorId(Throwable e)
+ private static List<String> _getErrorId(Throwable... exs)
{
- String message = e.getMessage();
-
- if (message == null)
- return null;
-
- List<String> list = new ArrayList<String>();
- Pattern pattern = Pattern.compile(REGEX_PATTERN);
- Matcher matcher = pattern.matcher(message);
-
- while (matcher.find())
+ List<String> list = null;
+ for (Throwable e : exs)
{
- list.add(matcher.group(1));
+ String message = e.getMessage();
+
+ if (message == null)
+ continue;
+
+ Pattern pattern = Pattern.compile(REGEX_PATTERN);
+ Matcher matcher = pattern.matcher(message);
+
+ while (matcher.find())
+ {
+ if (list == null)
+ {
+ list = new ArrayList<String>();
+ }
+ list.add(matcher.group(1));
+ }
}
- if (list.size() > 0)
+ if (list != null && list.size() > 0)
+ {
return list;
+ }
return null;
}