package org.jenkinsci.plugins.github.common;
import hudson.model.Run;
import hudson.model.TaskListener;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.annotation.Nonnull;
import java.util.ArrayList;
import java.util.List;
import static org.apache.commons.collections.CollectionUtils.isNotEmpty;
/**
* With help of list of other error handlers handles exception.
* If no one will handle it, exception will be wrapped to {@link ErrorHandlingException}
* and thrown by the handle method
*
* @author lanwen (Merkushev Kirill)
* @since 1.19.0
*/
public class CombineErrorHandler implements ErrorHandler {
private static final Logger LOG = LoggerFactory.getLogger(CombineErrorHandler.class);
private List<ErrorHandler> handlers = new ArrayList<>();
private CombineErrorHandler() {
}
/**
* Static factory to produce new instance of this handler
*
* @return new instance
*/
public static CombineErrorHandler errorHandling() {
return new CombineErrorHandler();
}
public CombineErrorHandler withHandlers(List<? extends ErrorHandler> handlers) {
if (isNotEmpty(handlers)) {
this.handlers.addAll(handlers);
}
return this;
}
/**
* Handles exception with help of other handlers. If no one will handle it, it will be thrown to the top level
*
* @param e exception to handle (log, ignore, process, rethrow)
* @param run run object from the step
* @param listener listener object from the step
*
* @return true if exception handled or rethrows it
*/
@Override
public boolean handle(Exception e, @Nonnull Run<?, ?> run, @Nonnull TaskListener listener) {
LOG.debug("Exception in {} will be processed with {} handlers",
run.getParent().getName(), handlers.size(), e);
try {
for (ErrorHandler next : handlers) {
if (next.handle(e, run, listener)) {
LOG.debug("Exception in {} [{}] handled by [{}]",
run.getParent().getName(),
e.getMessage(),
next.getClass());
return true;
}
}
} catch (Exception unhandled) {
LOG.error("Exception in {} unhandled", run.getParent().getName(), unhandled);
throw new ErrorHandlingException(unhandled);
}
throw new ErrorHandlingException(e);
}
/**
* Wrapper for the not handled by this handler exceptions
*/
public static class ErrorHandlingException extends RuntimeException {
public ErrorHandlingException(Throwable cause) {
super(cause);
}
}
}