001/* 002 * Copyright 2006-2007 the original author or authors. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * https://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package org.springframework.batch.repeat.exception; 018 019import org.apache.commons.logging.Log; 020import org.apache.commons.logging.LogFactory; 021import org.springframework.classify.Classifier; 022import org.springframework.classify.ClassifierSupport; 023import org.springframework.batch.repeat.RepeatContext; 024import org.springframework.batch.repeat.RepeatException; 025 026/** 027 * Implementation of {@link ExceptionHandler} based on an {@link Classifier}. 028 * The classifier determines whether to log the exception or rethrow it. The 029 * keys in the classifier must be the same as the static enum in this class. 030 * 031 * @author Dave Syer 032 * 033 */ 034public class LogOrRethrowExceptionHandler implements ExceptionHandler { 035 036 /** 037 * Logging levels for the handler. 038 * 039 * @author Dave Syer 040 * 041 */ 042 public static enum Level { 043 044 /** 045 * Key for {@link Classifier} signalling that the throwable should be 046 * rethrown. If the throwable is not a RuntimeException it is wrapped in 047 * a {@link RepeatException}. 048 */ 049 RETHROW, 050 051 /** 052 * Key for {@link Classifier} signalling that the throwable should be 053 * logged at debug level. 054 */ 055 DEBUG, 056 057 /** 058 * Key for {@link Classifier} signalling that the throwable should be 059 * logged at warn level. 060 */ 061 WARN, 062 063 /** 064 * Key for {@link Classifier} signalling that the throwable should be 065 * logged at error level. 066 */ 067 ERROR 068 069 } 070 071 protected final Log logger = LogFactory.getLog(LogOrRethrowExceptionHandler.class); 072 073 private Classifier<Throwable, Level> exceptionClassifier = new ClassifierSupport<Throwable, Level>(Level.RETHROW); 074 075 /** 076 * Setter for the {@link Classifier} used by this handler. The default is to 077 * map all throwable instances to {@link Level#RETHROW}. 078 * 079 * @param exceptionClassifier the ExceptionClassifier to use 080 */ 081 public void setExceptionClassifier(Classifier<Throwable, Level> exceptionClassifier) { 082 this.exceptionClassifier = exceptionClassifier; 083 } 084 085 /** 086 * Classify the throwables and decide whether to rethrow based on the 087 * result. The context is not used. 088 * 089 * @throws Throwable thrown if {@link LogOrRethrowExceptionHandler#exceptionClassifier} 090 * is classified as {@link Level#RETHROW}. 091 * 092 * @see ExceptionHandler#handleException(RepeatContext, Throwable) 093 */ 094 @Override 095 public void handleException(RepeatContext context, Throwable throwable) throws Throwable { 096 097 Level key = exceptionClassifier.classify(throwable); 098 if (Level.ERROR.equals(key)) { 099 logger.error("Exception encountered in batch repeat.", throwable); 100 } 101 else if (Level.WARN.equals(key)) { 102 logger.warn("Exception encountered in batch repeat.", throwable); 103 } 104 else if (Level.DEBUG.equals(key) && logger.isDebugEnabled()) { 105 logger.debug("Exception encountered in batch repeat.", throwable); 106 } 107 else if (Level.RETHROW.equals(key)) { 108 throw throwable; 109 } 110 111 } 112 113}