{
creationalContext = beanManager.createCreationalContext(null);
final Set<HandlerMethod<?>> processedHandlers = new HashSet<HandlerMethod<?>>();
final ExceptionStackEvent stack = new ExceptionStackEvent(exceptionEventEvent.getException());
beanManager.fireEvent(stack); // Allow for modifying the exception stack
inbound_cause:
//indentation needed by the current checkstyle rules
while (stack.getCurrent() != null)
{
final List<HandlerMethod<?>> callbackExceptionEvent = new ArrayList<HandlerMethod<?>>(
handlerMethodStorage.getHandlersForException(stack.getCurrent().getClass(),
beanManager, exceptionEventEvent.getQualifiers(), true));
for (HandlerMethod<?> handler : callbackExceptionEvent)
{
if (!processedHandlers.contains(handler))
{
LOG.fine(String.format("Notifying handler %s", handler));
@SuppressWarnings("rawtypes")
final DefaultExceptionEvent callbackEvent = new DefaultExceptionEvent(stack, true,
exceptionEventEvent.isHandled());
handler.notify(callbackEvent, beanManager);
LOG.fine(String.format("Handler %s returned status %s", handler,
callbackEvent.getCurrentExceptionHandlingFlow().name()));
if (!callbackEvent.isUnmute())
{
processedHandlers.add(handler);
}
switch (callbackEvent.getCurrentExceptionHandlingFlow())
{
case HANDLED:
exceptionEventEvent.setHandled(true);
return;
case HANDLED_AND_CONTINUE:
exceptionEventEvent.setHandled(true);
break;
case ABORT:
return;
case SKIP_CAUSE:
exceptionEventEvent.setHandled(true);
stack.skipCause();
continue inbound_cause;
case THROW_ORIGINAL:
throwException = exceptionEventEvent.getException();
break;
case THROW:
throwException = callbackEvent.getThrowNewException();
break;
default:
throw new IllegalStateException(
"Unexpected enum type " + callbackEvent.getCurrentExceptionHandlingFlow());
}
}
}
final Collection<HandlerMethod<? extends Throwable>> handlersForException =
handlerMethodStorage.getHandlersForException(stack.getCurrent().getClass(),
beanManager, exceptionEventEvent.getQualifiers(), false);
final List<HandlerMethod<? extends Throwable>> handlerMethods =
new ArrayList<HandlerMethod<? extends Throwable>>(handlersForException);
// Reverse these so category handlers are last
Collections.reverse(handlerMethods);
for (HandlerMethod<?> handler : handlerMethods)
{
if (!processedHandlers.contains(handler))
{
LOG.fine(String.format("Notifying handler %s", handler));
@SuppressWarnings("rawtypes")
final DefaultExceptionEvent depthFirstEvent = new DefaultExceptionEvent(stack, false,
exceptionEventEvent.isHandled());
handler.notify(depthFirstEvent, beanManager);
LOG.fine(String.format("Handler %s returned status %s", handler,
depthFirstEvent.getCurrentExceptionHandlingFlow().name()));
if (!depthFirstEvent.isUnmute())
{
processedHandlers.add(handler);
}
switch (depthFirstEvent.getCurrentExceptionHandlingFlow())
{
case HANDLED:
exceptionEventEvent.setHandled(true);
return;
case HANDLED_AND_CONTINUE:
exceptionEventEvent.setHandled(true);
break;
case ABORT:
return;
case SKIP_CAUSE:
exceptionEventEvent.setHandled(true);
stack.skipCause();
continue inbound_cause;
case THROW_ORIGINAL:
throwException = exceptionEventEvent.getException();
break;
case THROW:
throwException = depthFirstEvent.getThrowNewException();
break;
default:
throw new IllegalStateException(
"Unexpected enum type " + depthFirstEvent.getCurrentExceptionHandlingFlow());
}
}
}
stack.skipCause();
}
if (!exceptionEventEvent.isHandled() && throwException == null && !exceptionEventEvent.isOptional())
{
LOG.warning(String.format("No handlers found for exception %s", exceptionEventEvent.getException()));