Exception handling for phase listeners behaves differently depending on if they are registered globally in faces-config.xml or with f:phaseListener for a particular view root.
In the first (global) case any exception thrown by them gets forwarded to an exception handler as described in the spec.
In the second (per view root) case all exceptions get logged and swallowed as described in the UIViewRoot documentation.
This inconsistent behavior adds increased complexity when implementing PhaseListeners. Ideally both cases should forward any exception to the exception handler so they can be handled there.
See also the discussion of the problem in: https://java.net/jira/browse/JAVASERVERFACES-2985