/* * Copyright (c) MuleSoft, Inc. All rights reserved. http://www.mulesoft.com * The software in this package is published under the terms of the CPAL v1.0 * license, a copy of which has been included with this distribution in the * LICENSE.txt file. */ package org.mule.runtime.module.extension.internal.runtime.exception; import static org.mule.runtime.core.util.ExceptionUtils.extractCauseOfType; import static org.mule.runtime.core.util.ExceptionUtils.extractConnectionException; import org.mule.runtime.api.connection.ConnectionException; import org.mule.runtime.api.meta.model.ComponentModel; import org.mule.runtime.api.meta.model.EnrichableModel; import org.mule.runtime.api.meta.model.ExtensionModel; import org.mule.runtime.extension.api.runtime.exception.ExceptionHandler; import org.mule.runtime.module.extension.internal.loader.java.property.ExceptionHandlerModelProperty; import java.lang.reflect.UndeclaredThrowableException; import java.util.Optional; /** * Given a {@link ExtensionModel} and another {@link EnrichableModel}, this class will * test for a {@link ExceptionHandlerModelProperty} to determine the {@link ExceptionHandler} * which should be use. If no such property is available then a default {@link NullExceptionHandler} * is used. * <p> * It also contains all the logic for operations and sources {@link Throwable} process and handling. * * @since 4.0 */ public final class ExceptionHandlerManager { private static final ExceptionHandler DEFAULT_EXCEPTION_ENRICHER = new NullExceptionHandler(); private final ExceptionHandler exceptionHandler; public ExceptionHandlerManager(ExtensionModel extensionModel, ComponentModel componentModel) { exceptionHandler = findExceptionHandler(extensionModel, componentModel); } public Exception processException(Throwable t) { Exception handledException = handleException(t); Exception exception = exceptionHandler.enrichException(handledException); return exception != null ? exception : handledException; } public Exception handleException(Throwable e) { Throwable handled; Optional<ConnectionException> connectionException = extractConnectionException(e); if (connectionException.isPresent()) { handled = connectionException.get(); } else { // unwraps the exception thrown by the reflective operation if exist any. handled = extractCauseOfType(e, UndeclaredThrowableException.class).orElse(e); } return wrapInException(handled); } private Exception wrapInException(Throwable t) { return t instanceof Exception ? (Exception) t : new Exception(t); } private ExceptionHandler findExceptionHandler(ExtensionModel extension, EnrichableModel child) { return findExceptionHandler(child).orElseGet(() -> findExceptionHandler(extension).orElse(DEFAULT_EXCEPTION_ENRICHER)); } private Optional<ExceptionHandler> findExceptionHandler(EnrichableModel model) { return model.getModelProperty(ExceptionHandlerModelProperty.class) .map(p -> p.getExceptionHandlerFactory().createHandler()); } ExceptionHandler getExceptionHandler() { return exceptionHandler; } }