/* * Copyright 2014, The Sporting Exchange Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.betfair.cougar.core.api.exception; import java.util.HashMap; import java.util.Map; import java.util.logging.Level; import com.betfair.cougar.api.ResponseCode; import com.betfair.cougar.core.api.fault.Fault; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * An Exception that automatically logs itself */ @SuppressWarnings("serial") public abstract class CougarException extends RuntimeException { private final ServerFaultCode serverFault; private static Map<Class<? extends CougarException>,Logger> loggers = new HashMap<>(); CougarException(Level level, ServerFaultCode serverFault) { super(); this.serverFault = serverFault; logMe(serverFault, level); } CougarException(Level level, ServerFaultCode serverFault, Throwable e) { super(e); this.serverFault = serverFault; logMe(serverFault, level); } CougarException(Level level, ServerFaultCode serverFault, String cause) { super(cause); this.serverFault = serverFault; logMe(serverFault, level); } CougarException(Level level, ServerFaultCode serverFault, String cause, Throwable t) { super(cause, t); this.serverFault = serverFault; logMe(serverFault, level); } private Logger getLogger() { Class<? extends CougarException> c = getClass(); Logger logger = loggers.get(c); if (logger == null) { logger = LoggerFactory.getLogger(c); loggers.put(c, logger); } return logger; } private void logMe(ServerFaultCode serverFault, Level level) { // If it's an internal error, then we should always log. // A client fault is only logged if we're on debug logging. if (ResponseCode.InternalError == serverFault.getResponseCode()) { level = Level.WARNING; } Logger logger = getLogger(); String additionalInfo = additionalInfo(); String message = additionalInfo == null ? "Exception thrown" : "Exception thrown: " + additionalInfo; if (level.equals(Level.SEVERE)) { logger.error(message, this); } else if (level.equals(Level.WARNING)) { logger.warn(message, this); } else { logger.debug(message, this); } } public Fault getFault() { return new Fault(getResponseCode().getFaultCode(), serverFault.getDetail(), getMessage(), getCause()); } public ResponseCode getResponseCode() { return serverFault.getResponseCode(); } // Prevent defined services overriding the exception message @Override public final String getMessage() { String additional = additionalInfo(); return additional == null ? super.getMessage() : super.getMessage() + ": " + additional; } protected String additionalInfo() { return null; } public ServerFaultCode getServerFaultCode() { return serverFault; } }