You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@myfaces.apache.org by "Dirk Möbius (JIRA)" <de...@myfaces.apache.org> on 2009/04/24 10:16:30 UTC

[jira] Created: (MYFACES-2216) MyFaces silently ignores unhandled exceptions thrown in ActionListeners

MyFaces silently ignores unhandled exceptions thrown in ActionListeners
-----------------------------------------------------------------------

                 Key: MYFACES-2216
                 URL: https://issues.apache.org/jira/browse/MYFACES-2216
             Project: MyFaces Core
          Issue Type: Bug
          Components: JSR-252
    Affects Versions: 1.2.6, 1.2.7-SNAPSHOT
         Environment: Tomcat 6.0.18, JRE 1.6.11
            Reporter: Dirk Möbius


Have a look at the following stack trace when a custom ActionListener throws an unhandled exception:

com.myproject.validation.ValidationException
 	at com.myproject.controller.MyController.validate(MyController.java:50)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
	at java.lang.reflect.Method.invoke(Method.java:597)
	at org.apache.el.parser.AstValue.invoke(AstValue.java:172)
	at org.apache.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:276)
	at org.apache.jasper.el.JspMethodExpression.invoke(JspMethodExpression.java:68)
	at javax.faces.event.MethodExpressionActionListener.processAction(MethodExpressionActionListener.java:49)
	at javax.faces.event.ActionEvent.processListener(ActionEvent.java:51)
	at javax.faces.component.UIComponentBase.broadcast(UIComponentBase.java:554)
	at javax.faces.component.UICommand.broadcast(UICommand.java:124)
	at javax.faces.component.UIViewRoot._broadcastForPhase(UIViewRoot.java:369)
	at javax.faces.component.UIViewRoot.process(UIViewRoot.java:264)
	at javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java:153)
	at org.apache.myfaces.lifecycle.InvokeApplicationExecutor.execute(InvokeApplicationExecutor.java:32)
	at org.apache.myfaces.lifecycle.LifecycleImpl.executePhase(LifecycleImpl.java:103)
	at org.apache.myfaces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:76)
	at org.apache.myfaces.custom.ppr.PPRLifecycleWrapper.execute(PPRLifecycleWrapper.java:68)
	at javax.faces.webapp.FacesServlet.service(FacesServlet.java:151)

In MethodExpressionActionListener.processAction(ActionEvent), any exception is wrapped into an AbortProcessingException:

    public void processAction(ActionEvent actionEvent) throws AbortProcessingException {
        try {
            Object[] params = new Object[]{actionEvent};
            methodExpression.invoke(elContext(), params);
        } catch (Exception e) {
            throw new AbortProcessingException(e);
        }
    }

Deeper down in the stack trace, any AbortProcessingException is silently ignored in method UIViewRoot.__broadcastForPhase(PhaseId phaseId) : 

    private void _broadcastForPhase(PhaseId phaseId) {
        ...
                try
                {
                    source.broadcast(event);
                }
                catch (AbortProcessingException e)
                {
                    // abort event processing
                    // Page 3-30 of JSF 1.1 spec: "Throw an
                    // AbortProcessingException, to tell the JSF implementation
                    // that no further broadcast of this event, or any further
                    // events, should take place."
                    abort = true;
                    break;
                }
        ...
    }

Mojarra logs the exception at least (twice, in fact). But IMHO unhandled exceptions should make it to the top-level to be handled by custom error handlers or phase listeners. The spec is not explicit about unhandled exceptions in ActionListeners. Sec 3.4.7 ("Event broadcasting") simply states:

During event broadcasting, a listener processing an event may:
* Examine or modify the state of any component in the component tree.
* Add or remove components from the component tree.
* Add messages to be returned to the user, by calling addMessage on the
FacesContext instance for the current request.
* Queue one or more additional events, from the same source component or a different one,
for processing during the current lifecycle phase.
* Throw an AbortProcessingException, to tell the JSF implementation that no
further broadcast of this event, or any further events, should take place.
* Call renderResponse() on the FacesContext instance for the current request.[...]
* Call responseComplete() on the FacesContext instance for the current request.[...]

The best solution, IMHO, would be that MyFaces stores the unhandled exception in its internal queued exception list (request param "org.apache.myfaces.errorHandling.exceptionList") so that it won't get lost and can be inspected by custom code later.



-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


[jira] Commented: (MYFACES-2216) MyFaces silently ignores unhandled exceptions thrown in ActionListeners

Posted by "Dirk Möbius (JIRA)" <de...@myfaces.apache.org>.
    [ https://issues.apache.org/jira/browse/MYFACES-2216?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12702286#action_12702286 ] 

Dirk Möbius commented on MYFACES-2216:
--------------------------------------

Note: MyFaces 1.1 had a different behavior. Unhandled exceptions went through; an AbortProcessingException was only propagated if it had been raised explicitely by the ActionListener:

// from MyFaces 1.1 UICommand.java:
public void broadcast(FacesEvent event)
        throws AbortProcessingException
{
        super.broadcast(event);

        if (event instanceof ActionEvent)
        {
            FacesContext context = getFacesContext();

            MethodBinding actionListenerBinding = getActionListener();
            if (actionListenerBinding != null)
            {
                try
                {
                    actionListenerBinding.invoke(context, new Object[] {event});
                }
                catch (EvaluationException e)
                {
                    Throwable cause = e.getCause();
                    if (cause != null && cause instanceof AbortProcessingException)
                    {
                        throw (AbortProcessingException)cause;
                    }
                    else
                    {
                        throw e;
                    }
                }
            }
            ...
        }
}


> MyFaces silently ignores unhandled exceptions thrown in ActionListeners
> -----------------------------------------------------------------------
>
>                 Key: MYFACES-2216
>                 URL: https://issues.apache.org/jira/browse/MYFACES-2216
>             Project: MyFaces Core
>          Issue Type: Bug
>          Components: JSR-252
>    Affects Versions: 1.2.6, 1.2.7-SNAPSHOT
>         Environment: Tomcat 6.0.18, JRE 1.6.11
>            Reporter: Dirk Möbius
>
> Have a look at the following stack trace when a custom ActionListener throws an unhandled exception:
> com.myproject.validation.ValidationException
>  	at com.myproject.controller.MyController.validate(MyController.java:50)
> 	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
> 	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
> 	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
> 	at java.lang.reflect.Method.invoke(Method.java:597)
> 	at org.apache.el.parser.AstValue.invoke(AstValue.java:172)
> 	at org.apache.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:276)
> 	at org.apache.jasper.el.JspMethodExpression.invoke(JspMethodExpression.java:68)
> 	at javax.faces.event.MethodExpressionActionListener.processAction(MethodExpressionActionListener.java:49)
> 	at javax.faces.event.ActionEvent.processListener(ActionEvent.java:51)
> 	at javax.faces.component.UIComponentBase.broadcast(UIComponentBase.java:554)
> 	at javax.faces.component.UICommand.broadcast(UICommand.java:124)
> 	at javax.faces.component.UIViewRoot._broadcastForPhase(UIViewRoot.java:369)
> 	at javax.faces.component.UIViewRoot.process(UIViewRoot.java:264)
> 	at javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java:153)
> 	at org.apache.myfaces.lifecycle.InvokeApplicationExecutor.execute(InvokeApplicationExecutor.java:32)
> 	at org.apache.myfaces.lifecycle.LifecycleImpl.executePhase(LifecycleImpl.java:103)
> 	at org.apache.myfaces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:76)
> 	at org.apache.myfaces.custom.ppr.PPRLifecycleWrapper.execute(PPRLifecycleWrapper.java:68)
> 	at javax.faces.webapp.FacesServlet.service(FacesServlet.java:151)
> In MethodExpressionActionListener.processAction(ActionEvent), any exception is wrapped into an AbortProcessingException:
>     public void processAction(ActionEvent actionEvent) throws AbortProcessingException {
>         try {
>             Object[] params = new Object[]{actionEvent};
>             methodExpression.invoke(elContext(), params);
>         } catch (Exception e) {
>             throw new AbortProcessingException(e);
>         }
>     }
> Deeper down in the stack trace, any AbortProcessingException is silently ignored in method UIViewRoot.__broadcastForPhase(PhaseId phaseId) : 
>     private void _broadcastForPhase(PhaseId phaseId) {
>         ...
>                 try
>                 {
>                     source.broadcast(event);
>                 }
>                 catch (AbortProcessingException e)
>                 {
>                     // abort event processing
>                     // Page 3-30 of JSF 1.1 spec: "Throw an
>                     // AbortProcessingException, to tell the JSF implementation
>                     // that no further broadcast of this event, or any further
>                     // events, should take place."
>                     abort = true;
>                     break;
>                 }
>         ...
>     }
> Mojarra logs the exception at least (twice, in fact). But IMHO unhandled exceptions should make it to the top-level to be handled by custom error handlers or phase listeners. The spec is not explicit about unhandled exceptions in ActionListeners. Sec 3.4.7 ("Event broadcasting") simply states:
> During event broadcasting, a listener processing an event may:
> * Examine or modify the state of any component in the component tree.
> * Add or remove components from the component tree.
> * Add messages to be returned to the user, by calling addMessage on the
> FacesContext instance for the current request.
> * Queue one or more additional events, from the same source component or a different one,
> for processing during the current lifecycle phase.
> * Throw an AbortProcessingException, to tell the JSF implementation that no
> further broadcast of this event, or any further events, should take place.
> * Call renderResponse() on the FacesContext instance for the current request.[...]
> * Call responseComplete() on the FacesContext instance for the current request.[...]
> The best solution, IMHO, would be that MyFaces stores the unhandled exception in its internal queued exception list (request param "org.apache.myfaces.errorHandling.exceptionList") so that it won't get lost and can be inspected by custom code later.

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


[jira] Commented: (MYFACES-2216) MyFaces suppresses runtime exceptions thrown in ActionListeners

Posted by "Kaeri Johnson (JIRA)" <de...@myfaces.apache.org>.
    [ https://issues.apache.org/jira/browse/MYFACES-2216?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12765766#action_12765766 ] 

Kaeri Johnson commented on MYFACES-2216:
----------------------------------------

This issue is causing is great pains in production- is there a workaround or fix being implemented? 

> MyFaces suppresses runtime exceptions thrown in ActionListeners
> ---------------------------------------------------------------
>
>                 Key: MYFACES-2216
>                 URL: https://issues.apache.org/jira/browse/MYFACES-2216
>             Project: MyFaces Core
>          Issue Type: Bug
>          Components: JSR-252
>    Affects Versions: 1.2.6, 1.2.7-SNAPSHOT
>         Environment: Tomcat 6.0.18, JRE 1.6.11
>            Reporter: Dirk Möbius
>
> Have a look at the following stack trace when a custom ActionListener throws an unhandled exception:
> com.myproject.validation.ValidationException
>  	at com.myproject.controller.MyController.validate(MyController.java:50)
> 	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
> 	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
> 	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
> 	at java.lang.reflect.Method.invoke(Method.java:597)
> 	at org.apache.el.parser.AstValue.invoke(AstValue.java:172)
> 	at org.apache.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:276)
> 	at org.apache.jasper.el.JspMethodExpression.invoke(JspMethodExpression.java:68)
> 	at javax.faces.event.MethodExpressionActionListener.processAction(MethodExpressionActionListener.java:49)
> 	at javax.faces.event.ActionEvent.processListener(ActionEvent.java:51)
> 	at javax.faces.component.UIComponentBase.broadcast(UIComponentBase.java:554)
> 	at javax.faces.component.UICommand.broadcast(UICommand.java:124)
> 	at javax.faces.component.UIViewRoot._broadcastForPhase(UIViewRoot.java:369)
> 	at javax.faces.component.UIViewRoot.process(UIViewRoot.java:264)
> 	at javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java:153)
> 	at org.apache.myfaces.lifecycle.InvokeApplicationExecutor.execute(InvokeApplicationExecutor.java:32)
> 	at org.apache.myfaces.lifecycle.LifecycleImpl.executePhase(LifecycleImpl.java:103)
> 	at org.apache.myfaces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:76)
> 	at org.apache.myfaces.custom.ppr.PPRLifecycleWrapper.execute(PPRLifecycleWrapper.java:68)
> 	at javax.faces.webapp.FacesServlet.service(FacesServlet.java:151)
> In MethodExpressionActionListener.processAction(ActionEvent), any exception is wrapped into an AbortProcessingException:
>     public void processAction(ActionEvent actionEvent) throws AbortProcessingException {
>         try {
>             Object[] params = new Object[]{actionEvent};
>             methodExpression.invoke(elContext(), params);
>         } catch (Exception e) {
>             throw new AbortProcessingException(e);
>         }
>     }
> Deeper down in the stack trace, any AbortProcessingException is silently ignored in method UIViewRoot.__broadcastForPhase(PhaseId phaseId) : 
>     private void _broadcastForPhase(PhaseId phaseId) {
>         ...
>                 try
>                 {
>                     source.broadcast(event);
>                 }
>                 catch (AbortProcessingException e)
>                 {
>                     // abort event processing
>                     // Page 3-30 of JSF 1.1 spec: "Throw an
>                     // AbortProcessingException, to tell the JSF implementation
>                     // that no further broadcast of this event, or any further
>                     // events, should take place."
>                     abort = true;
>                     break;
>                 }
>         ...
>     }
> Mojarra logs the exception at least (twice, in fact). But IMHO unhandled exceptions should make it to the top-level to be handled by custom error handlers or phase listeners. The spec is not explicit about unhandled exceptions in ActionListeners. Sec 3.4.7 ("Event broadcasting") simply states:
> During event broadcasting, a listener processing an event may:
> * Examine or modify the state of any component in the component tree.
> * Add or remove components from the component tree.
> * Add messages to be returned to the user, by calling addMessage on the
> FacesContext instance for the current request.
> * Queue one or more additional events, from the same source component or a different one,
> for processing during the current lifecycle phase.
> * Throw an AbortProcessingException, to tell the JSF implementation that no
> further broadcast of this event, or any further events, should take place.
> * Call renderResponse() on the FacesContext instance for the current request.[...]
> * Call responseComplete() on the FacesContext instance for the current request.[...]
> The best solution, IMHO, would be that MyFaces stores the unhandled exception in its internal queued exception list (request param "org.apache.myfaces.errorHandling.exceptionList") so that it won't get lost and can be inspected by custom code later.

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


[jira] Resolved: (MYFACES-2216) MyFaces suppresses runtime exceptions thrown in ActionListeners

Posted by "Leonardo Uribe (JIRA)" <de...@myfaces.apache.org>.
     [ https://issues.apache.org/jira/browse/MYFACES-2216?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Leonardo Uribe resolved MYFACES-2216.
-------------------------------------

       Resolution: Fixed
    Fix Version/s: 1.2.8-SNAPSHOT

> MyFaces suppresses runtime exceptions thrown in ActionListeners
> ---------------------------------------------------------------
>
>                 Key: MYFACES-2216
>                 URL: https://issues.apache.org/jira/browse/MYFACES-2216
>             Project: MyFaces Core
>          Issue Type: Bug
>          Components: JSR-252
>    Affects Versions: 1.2.6, 1.2.7-SNAPSHOT
>         Environment: Tomcat 6.0.18, JRE 1.6.11
>            Reporter: Dirk Möbius
>            Assignee: Leonardo Uribe
>             Fix For: 1.2.8-SNAPSHOT
>
>
> Have a look at the following stack trace when a custom ActionListener throws an unhandled exception:
> com.myproject.validation.ValidationException
>  	at com.myproject.controller.MyController.validate(MyController.java:50)
> 	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
> 	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
> 	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
> 	at java.lang.reflect.Method.invoke(Method.java:597)
> 	at org.apache.el.parser.AstValue.invoke(AstValue.java:172)
> 	at org.apache.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:276)
> 	at org.apache.jasper.el.JspMethodExpression.invoke(JspMethodExpression.java:68)
> 	at javax.faces.event.MethodExpressionActionListener.processAction(MethodExpressionActionListener.java:49)
> 	at javax.faces.event.ActionEvent.processListener(ActionEvent.java:51)
> 	at javax.faces.component.UIComponentBase.broadcast(UIComponentBase.java:554)
> 	at javax.faces.component.UICommand.broadcast(UICommand.java:124)
> 	at javax.faces.component.UIViewRoot._broadcastForPhase(UIViewRoot.java:369)
> 	at javax.faces.component.UIViewRoot.process(UIViewRoot.java:264)
> 	at javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java:153)
> 	at org.apache.myfaces.lifecycle.InvokeApplicationExecutor.execute(InvokeApplicationExecutor.java:32)
> 	at org.apache.myfaces.lifecycle.LifecycleImpl.executePhase(LifecycleImpl.java:103)
> 	at org.apache.myfaces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:76)
> 	at org.apache.myfaces.custom.ppr.PPRLifecycleWrapper.execute(PPRLifecycleWrapper.java:68)
> 	at javax.faces.webapp.FacesServlet.service(FacesServlet.java:151)
> In MethodExpressionActionListener.processAction(ActionEvent), any exception is wrapped into an AbortProcessingException:
>     public void processAction(ActionEvent actionEvent) throws AbortProcessingException {
>         try {
>             Object[] params = new Object[]{actionEvent};
>             methodExpression.invoke(elContext(), params);
>         } catch (Exception e) {
>             throw new AbortProcessingException(e);
>         }
>     }
> Deeper down in the stack trace, any AbortProcessingException is silently ignored in method UIViewRoot.__broadcastForPhase(PhaseId phaseId) : 
>     private void _broadcastForPhase(PhaseId phaseId) {
>         ...
>                 try
>                 {
>                     source.broadcast(event);
>                 }
>                 catch (AbortProcessingException e)
>                 {
>                     // abort event processing
>                     // Page 3-30 of JSF 1.1 spec: "Throw an
>                     // AbortProcessingException, to tell the JSF implementation
>                     // that no further broadcast of this event, or any further
>                     // events, should take place."
>                     abort = true;
>                     break;
>                 }
>         ...
>     }
> Mojarra logs the exception at least (twice, in fact). But IMHO unhandled exceptions should make it to the top-level to be handled by custom error handlers or phase listeners. The spec is not explicit about unhandled exceptions in ActionListeners. Sec 3.4.7 ("Event broadcasting") simply states:
> During event broadcasting, a listener processing an event may:
> * Examine or modify the state of any component in the component tree.
> * Add or remove components from the component tree.
> * Add messages to be returned to the user, by calling addMessage on the
> FacesContext instance for the current request.
> * Queue one or more additional events, from the same source component or a different one,
> for processing during the current lifecycle phase.
> * Throw an AbortProcessingException, to tell the JSF implementation that no
> further broadcast of this event, or any further events, should take place.
> * Call renderResponse() on the FacesContext instance for the current request.[...]
> * Call responseComplete() on the FacesContext instance for the current request.[...]
> The best solution, IMHO, would be that MyFaces stores the unhandled exception in its internal queued exception list (request param "org.apache.myfaces.errorHandling.exceptionList") so that it won't get lost and can be inspected by custom code later.

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


[jira] Commented: (MYFACES-2216) MyFaces suppresses runtime exceptions thrown in ActionListeners

Posted by "Martin Marinschek (JIRA)" <de...@myfaces.apache.org>.
    [ https://issues.apache.org/jira/browse/MYFACES-2216?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12765878#action_12765878 ] 

Martin Marinschek commented on MYFACES-2216:
--------------------------------------------

This behaviour is of course not what we want. I have just yesterday informed the Mojarra team of the very same issue in the RI. We should definitely fix it in MyFaces as well. The idea would be to do exactly the same as MyFaces 1.1 was doing. I don't have a clue why this code was changed.

Leonardo, that is a very simple fix, can you take care?

regards,

Martin

> MyFaces suppresses runtime exceptions thrown in ActionListeners
> ---------------------------------------------------------------
>
>                 Key: MYFACES-2216
>                 URL: https://issues.apache.org/jira/browse/MYFACES-2216
>             Project: MyFaces Core
>          Issue Type: Bug
>          Components: JSR-252
>    Affects Versions: 1.2.6, 1.2.7-SNAPSHOT
>         Environment: Tomcat 6.0.18, JRE 1.6.11
>            Reporter: Dirk Möbius
>            Assignee: Leonardo Uribe
>
> Have a look at the following stack trace when a custom ActionListener throws an unhandled exception:
> com.myproject.validation.ValidationException
>  	at com.myproject.controller.MyController.validate(MyController.java:50)
> 	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
> 	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
> 	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
> 	at java.lang.reflect.Method.invoke(Method.java:597)
> 	at org.apache.el.parser.AstValue.invoke(AstValue.java:172)
> 	at org.apache.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:276)
> 	at org.apache.jasper.el.JspMethodExpression.invoke(JspMethodExpression.java:68)
> 	at javax.faces.event.MethodExpressionActionListener.processAction(MethodExpressionActionListener.java:49)
> 	at javax.faces.event.ActionEvent.processListener(ActionEvent.java:51)
> 	at javax.faces.component.UIComponentBase.broadcast(UIComponentBase.java:554)
> 	at javax.faces.component.UICommand.broadcast(UICommand.java:124)
> 	at javax.faces.component.UIViewRoot._broadcastForPhase(UIViewRoot.java:369)
> 	at javax.faces.component.UIViewRoot.process(UIViewRoot.java:264)
> 	at javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java:153)
> 	at org.apache.myfaces.lifecycle.InvokeApplicationExecutor.execute(InvokeApplicationExecutor.java:32)
> 	at org.apache.myfaces.lifecycle.LifecycleImpl.executePhase(LifecycleImpl.java:103)
> 	at org.apache.myfaces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:76)
> 	at org.apache.myfaces.custom.ppr.PPRLifecycleWrapper.execute(PPRLifecycleWrapper.java:68)
> 	at javax.faces.webapp.FacesServlet.service(FacesServlet.java:151)
> In MethodExpressionActionListener.processAction(ActionEvent), any exception is wrapped into an AbortProcessingException:
>     public void processAction(ActionEvent actionEvent) throws AbortProcessingException {
>         try {
>             Object[] params = new Object[]{actionEvent};
>             methodExpression.invoke(elContext(), params);
>         } catch (Exception e) {
>             throw new AbortProcessingException(e);
>         }
>     }
> Deeper down in the stack trace, any AbortProcessingException is silently ignored in method UIViewRoot.__broadcastForPhase(PhaseId phaseId) : 
>     private void _broadcastForPhase(PhaseId phaseId) {
>         ...
>                 try
>                 {
>                     source.broadcast(event);
>                 }
>                 catch (AbortProcessingException e)
>                 {
>                     // abort event processing
>                     // Page 3-30 of JSF 1.1 spec: "Throw an
>                     // AbortProcessingException, to tell the JSF implementation
>                     // that no further broadcast of this event, or any further
>                     // events, should take place."
>                     abort = true;
>                     break;
>                 }
>         ...
>     }
> Mojarra logs the exception at least (twice, in fact). But IMHO unhandled exceptions should make it to the top-level to be handled by custom error handlers or phase listeners. The spec is not explicit about unhandled exceptions in ActionListeners. Sec 3.4.7 ("Event broadcasting") simply states:
> During event broadcasting, a listener processing an event may:
> * Examine or modify the state of any component in the component tree.
> * Add or remove components from the component tree.
> * Add messages to be returned to the user, by calling addMessage on the
> FacesContext instance for the current request.
> * Queue one or more additional events, from the same source component or a different one,
> for processing during the current lifecycle phase.
> * Throw an AbortProcessingException, to tell the JSF implementation that no
> further broadcast of this event, or any further events, should take place.
> * Call renderResponse() on the FacesContext instance for the current request.[...]
> * Call responseComplete() on the FacesContext instance for the current request.[...]
> The best solution, IMHO, would be that MyFaces stores the unhandled exception in its internal queued exception list (request param "org.apache.myfaces.errorHandling.exceptionList") so that it won't get lost and can be inspected by custom code later.

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


[jira] Commented: (MYFACES-2216) MyFaces suppresses runtime exceptions thrown in ActionListeners

Posted by "Leonardo Uribe (JIRA)" <de...@myfaces.apache.org>.
    [ https://issues.apache.org/jira/browse/MYFACES-2216?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12770120#action_12770120 ] 

Leonardo Uribe commented on MYFACES-2216:
-----------------------------------------

It seems to be a misunderstanding about the javadoc of javax.faces.event.MethodExpressionActionListener and MethodExpressionValueChangeListener

the javadoc says:

Throws:
    java.lang.NullPointerException 
    AbortProcessingException - Signal the JavaServer Faces implementation that no further processing on the current event should be performed

But the real intention is that if the cause is by an AbortProcessingException, no further processing should be performed. Otherwise (like a RuntimeException), an error is thrown.

The new code in both classes is this:

        try
        {
            Object[] params = new Object[]{event};
            methodExpression.invoke(elContext(), params);
        }
        catch (ELException e)
        {
            Throwable cause = e.getCause();
            if (cause != null && cause instanceof AbortProcessingException)
            {
                throw (AbortProcessingException)cause;
            }
            else
            {
                throw e;
            }
        }

Like in 1.1.

> MyFaces suppresses runtime exceptions thrown in ActionListeners
> ---------------------------------------------------------------
>
>                 Key: MYFACES-2216
>                 URL: https://issues.apache.org/jira/browse/MYFACES-2216
>             Project: MyFaces Core
>          Issue Type: Bug
>          Components: JSR-252
>    Affects Versions: 1.2.6, 1.2.7-SNAPSHOT
>         Environment: Tomcat 6.0.18, JRE 1.6.11
>            Reporter: Dirk Möbius
>            Assignee: Leonardo Uribe
>
> Have a look at the following stack trace when a custom ActionListener throws an unhandled exception:
> com.myproject.validation.ValidationException
>  	at com.myproject.controller.MyController.validate(MyController.java:50)
> 	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
> 	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
> 	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
> 	at java.lang.reflect.Method.invoke(Method.java:597)
> 	at org.apache.el.parser.AstValue.invoke(AstValue.java:172)
> 	at org.apache.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:276)
> 	at org.apache.jasper.el.JspMethodExpression.invoke(JspMethodExpression.java:68)
> 	at javax.faces.event.MethodExpressionActionListener.processAction(MethodExpressionActionListener.java:49)
> 	at javax.faces.event.ActionEvent.processListener(ActionEvent.java:51)
> 	at javax.faces.component.UIComponentBase.broadcast(UIComponentBase.java:554)
> 	at javax.faces.component.UICommand.broadcast(UICommand.java:124)
> 	at javax.faces.component.UIViewRoot._broadcastForPhase(UIViewRoot.java:369)
> 	at javax.faces.component.UIViewRoot.process(UIViewRoot.java:264)
> 	at javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java:153)
> 	at org.apache.myfaces.lifecycle.InvokeApplicationExecutor.execute(InvokeApplicationExecutor.java:32)
> 	at org.apache.myfaces.lifecycle.LifecycleImpl.executePhase(LifecycleImpl.java:103)
> 	at org.apache.myfaces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:76)
> 	at org.apache.myfaces.custom.ppr.PPRLifecycleWrapper.execute(PPRLifecycleWrapper.java:68)
> 	at javax.faces.webapp.FacesServlet.service(FacesServlet.java:151)
> In MethodExpressionActionListener.processAction(ActionEvent), any exception is wrapped into an AbortProcessingException:
>     public void processAction(ActionEvent actionEvent) throws AbortProcessingException {
>         try {
>             Object[] params = new Object[]{actionEvent};
>             methodExpression.invoke(elContext(), params);
>         } catch (Exception e) {
>             throw new AbortProcessingException(e);
>         }
>     }
> Deeper down in the stack trace, any AbortProcessingException is silently ignored in method UIViewRoot.__broadcastForPhase(PhaseId phaseId) : 
>     private void _broadcastForPhase(PhaseId phaseId) {
>         ...
>                 try
>                 {
>                     source.broadcast(event);
>                 }
>                 catch (AbortProcessingException e)
>                 {
>                     // abort event processing
>                     // Page 3-30 of JSF 1.1 spec: "Throw an
>                     // AbortProcessingException, to tell the JSF implementation
>                     // that no further broadcast of this event, or any further
>                     // events, should take place."
>                     abort = true;
>                     break;
>                 }
>         ...
>     }
> Mojarra logs the exception at least (twice, in fact). But IMHO unhandled exceptions should make it to the top-level to be handled by custom error handlers or phase listeners. The spec is not explicit about unhandled exceptions in ActionListeners. Sec 3.4.7 ("Event broadcasting") simply states:
> During event broadcasting, a listener processing an event may:
> * Examine or modify the state of any component in the component tree.
> * Add or remove components from the component tree.
> * Add messages to be returned to the user, by calling addMessage on the
> FacesContext instance for the current request.
> * Queue one or more additional events, from the same source component or a different one,
> for processing during the current lifecycle phase.
> * Throw an AbortProcessingException, to tell the JSF implementation that no
> further broadcast of this event, or any further events, should take place.
> * Call renderResponse() on the FacesContext instance for the current request.[...]
> * Call responseComplete() on the FacesContext instance for the current request.[...]
> The best solution, IMHO, would be that MyFaces stores the unhandled exception in its internal queued exception list (request param "org.apache.myfaces.errorHandling.exceptionList") so that it won't get lost and can be inspected by custom code later.

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.