001    /**
002     * Licensed to the Apache Software Foundation (ASF) under one or more
003     * contributor license agreements.  See the NOTICE file distributed with
004     * this work for additional information regarding copyright ownership.
005     * The ASF licenses this file to You under the Apache License, Version 2.0
006     * (the "License"); you may not use this file except in compliance with
007     * the License.  You may obtain a copy of the License at
008     *
009     *      http://www.apache.org/licenses/LICENSE-2.0
010     *
011     * Unless required by applicable law or agreed to in writing, software
012     * distributed under the License is distributed on an "AS IS" BASIS,
013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     * See the License for the specific language governing permissions and
015     * limitations under the License.
016     */
017    package org.apache.camel.impl;
018    
019    import org.apache.camel.CamelExchangeException;
020    import org.apache.camel.Exchange;
021    import org.apache.camel.LoggingLevel;
022    import org.apache.camel.RollbackExchangeException;
023    import org.apache.camel.spi.ExceptionHandler;
024    import org.apache.camel.util.CamelLogger;
025    import org.slf4j.LoggerFactory;
026    
027    /**
028     * A default implementation of {@link ExceptionHandler} which uses a {@link org.apache.camel.processor.CamelLogger} to
029     * log the exception.
030     * <p/>
031     * This implementation will by default log the exception with stack trace at WARN level.
032     *
033     * @version 
034     */
035    public class LoggingExceptionHandler implements ExceptionHandler {
036        private final CamelLogger logger;
037    
038        public LoggingExceptionHandler(Class<?> ownerType) {
039            this(new CamelLogger(LoggerFactory.getLogger(ownerType), LoggingLevel.WARN));
040        }
041    
042        public LoggingExceptionHandler(Class<?> ownerType, LoggingLevel level) {
043            this(new CamelLogger(LoggerFactory.getLogger(ownerType), level));
044        }
045    
046        public LoggingExceptionHandler(CamelLogger logger) {
047            this.logger = logger;
048        }
049    
050        public void handleException(Throwable exception) {
051            handleException(null, null, exception);
052        }
053    
054        public void handleException(String message, Throwable exception) {
055            handleException(message, null, exception);
056        }
057    
058        public void handleException(String message, Exchange exchange, Throwable exception) {
059            try {
060                String msg = CamelExchangeException.createExceptionMessage(message, exchange, exception);
061                if (isCausedByRollbackExchangeException(exception)) {
062                    // do not log stack trace for intended rollbacks
063                    logger.log(msg);
064                } else {
065                    if (exception != null) {
066                        logger.log(msg, exception);
067                    } else {
068                        logger.log(msg);
069                    }
070                }
071            } catch (Throwable e) {
072                // the logging exception handler must not cause new exceptions to occur
073            }
074        }
075    
076        protected boolean isCausedByRollbackExchangeException(Throwable exception) {
077            if (exception == null) {
078                return false;
079            }
080            if (exception instanceof RollbackExchangeException) {
081                return true;
082            } else if (exception.getCause() != null) {
083                // recursive children
084                return isCausedByRollbackExchangeException(exception.getCause());
085            }
086    
087            return false;
088        }
089    }