Search in sources :

Example 1 with ExceptionStackEvent

use of org.apache.deltaspike.core.api.exception.control.event.ExceptionStackEvent in project deltaspike by apache.

the class ExceptionHandlerBroadcaster method executeHandlers.

/**
     * Observes the event, finds the correct exception handler(s) and invokes them.
     * 
     * @param exceptionEventEvent
     *            exception to be invoked
     * @param beanManager
     *            active bean manager
     * @throws Throwable
     *             If a handler requests the exception to be re-thrown.
     */
public void executeHandlers(@Observes @Any ExceptionToCatchEvent exceptionEventEvent, final BeanManager beanManager) throws Throwable {
    LOG.entering(ExceptionHandlerBroadcaster.class.getName(), "executeHandlers", exceptionEventEvent.getException());
    CreationalContext<Object> creationalContext = null;
    Throwable throwException = null;
    final HandlerMethodStorage handlerMethodStorage = BeanProvider.getContextualReference(HandlerMethodStorage.class);
    try {
        creationalContext = beanManager.createCreationalContext(null);
        final Set<HandlerMethod<?>> processedHandlers = new HashSet<HandlerMethod<?>>();
        final ExceptionStackEvent stack = new ExceptionStackEvent(exceptionEventEvent.getException());
        // Allow for modifying the exception stack
        beanManager.fireEvent(stack);
        // indentation with 8 for label needed by the current checkstyle rules
        inbound_cause: 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:
                            throw exceptionEventEvent.getException();
                        case THROW:
                            throw callbackEvent.getThrowNewException();
                        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()));
            throw exceptionEventEvent.getException();
        }
        if (throwException != null) {
            throw throwException;
        }
    } finally {
        if (creationalContext != null) {
            creationalContext.release();
        }
        LOG.exiting(ExceptionHandlerBroadcaster.class.getName(), "executeHandlers", exceptionEventEvent.getException());
    }
}
Also used : HandlerMethod(org.apache.deltaspike.core.api.exception.control.HandlerMethod) ExceptionStackEvent(org.apache.deltaspike.core.api.exception.control.event.ExceptionStackEvent) Collection(java.util.Collection) ArrayList(java.util.ArrayList) List(java.util.List) HashSet(java.util.HashSet)

Aggregations

ArrayList (java.util.ArrayList)1 Collection (java.util.Collection)1 HashSet (java.util.HashSet)1 List (java.util.List)1 HandlerMethod (org.apache.deltaspike.core.api.exception.control.HandlerMethod)1 ExceptionStackEvent (org.apache.deltaspike.core.api.exception.control.event.ExceptionStackEvent)1