Index: oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentStoreException.java =================================================================== --- oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentStoreException.java (revision 1825859) +++ oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentStoreException.java (working copy) @@ -16,8 +16,14 @@ */ package org.apache.jackrabbit.oak.plugins.document; +import javax.annotation.CheckForNull; +import javax.annotation.Nonnull; + import com.google.common.collect.Lists; +import static com.google.common.base.Preconditions.checkNotNull; +import static java.util.Collections.emptyList; + /** * DocumentStoreException is a runtime exception for * {@code DocumentStore} implementations to signal unexpected problems like @@ -27,33 +33,162 @@ private static final long serialVersionUID = 634445274043721284L; + public enum Type { + + /** + * A generic type of {@code DocumentStoreException}. This type is used + * when no explicit type is given when a {@code DocumentStoreException} + * is constructed. + */ + GENERIC, + + /** + * A {@code DocumentStoreException} caused by a transient problem. E.g. + * a network issue. This type of exception indicates a future invocation + * of the same operation may succeed if the underlying problem gets + * resolved. + */ + TRANSIENT + } + + private final Type type; + + /** + * Creates a {@link Type#GENERIC} {@code DocumentStoreException} with the + * given message. + * + * @param message the exception message. + */ public DocumentStoreException(String message) { - super(message); + this(message, null); } + /** + * Creates a {@link Type#GENERIC} {@code DocumentStoreException} with the + * given cause. The message of the exception is the value returned by + * {@code cause.toString()} if available, otherwise {@code null}. + * + * @param cause the cause or {@code null} if nonexistent or unknown. + */ public DocumentStoreException(Throwable cause) { - super(cause); + this(getMessage(cause), cause); } + /** + * Creates a {@link Type#GENERIC} {@code DocumentStoreException} with the + * given message and cause. + * + * @param message the exception message. + * @param cause the cause or {@code null} if nonexistent or unknown. + */ public DocumentStoreException(String message, Throwable cause) { + this(message, cause, Type.GENERIC); + } + + /** + * Creates a {@code DocumentStoreException} with the given message, cause + * and type. + * + * @param message the exception message. + * @param cause the cause or {@code null} if nonexistent or unknown. + * @param type the type of this exception. + */ + public DocumentStoreException(String message, Throwable cause, Type type) { super(message, cause); + this.type = checkNotNull(type); } - public static DocumentStoreException convert(Throwable t) { + /** + * Converts the given {@code Throwable} into a {@link Type#GENERIC} + * {@code DocumentStoreException}. If the {@code Throwable} is an instance + * of {@code DocumentStoreException} this method returns the given + * {@code Throwable} as is, otherwise it will be used as the cause of the + * returned {@code DocumentStoreException}. The returned + * {@code DocumentStoreException} will have the same message as the given + * {@code Throwable}. + * + * @param t a {@code Throwable}. + * @return a {@link Type#GENERIC} DocumentStoreException. + */ + public static DocumentStoreException convert(@Nonnull Throwable t) { return convert(t, t.getMessage()); } - public static DocumentStoreException convert(Throwable t, String msg) { + /** + * Converts the given {@code Throwable} into a {@link Type#GENERIC} + * {@code DocumentStoreException}. If the {@code Throwable} is an instance + * of {@code DocumentStoreException} this method returns the given + * {@code Throwable} as is, otherwise it will be used as the cause of the + * returned {@code DocumentStoreException}. The returned + * {@code DocumentStoreException} will have the given message, unless the + * {@code Throwable} already is a {@code DocumentStoreException}. + * + * @param t a {@code Throwable}. + * @param msg a message for the {@code DocumentStoreException}. + * @return a {@link Type#GENERIC} DocumentStoreException. + */ + public static DocumentStoreException convert(@Nonnull Throwable t, String msg) { + return asDocumentStoreException(msg, t, Type.GENERIC, emptyList()); + } + + /** + * Converts the given {@code Throwable} into a {@link Type#GENERIC} + * {@code DocumentStoreException}. If the {@code Throwable} is an instance + * of {@code DocumentStoreException} this method returns the given + * {@code Throwable} as is, otherwise it will be used as the cause of the + * returned {@code DocumentStoreException}. The returned + * {@code DocumentStoreException} will have the same message as the given + * {@code Throwable} appended with the list of {@code ids}. + * + * @param t a {@code Throwable}. + * @param ids a list of {@code DocumentStore} IDs associated with the + * operation that triggered this exception. + * @return a {@link Type#GENERIC} DocumentStoreException. + */ + public static DocumentStoreException convert(@Nonnull Throwable t, + Iterable ids) { + return asDocumentStoreException(t.getMessage(), t, Type.GENERIC, ids); + } + + /** + * Converts the given {@code Throwable} into a {@code DocumentStoreException}. + * If the {@code Throwable} is an instance of {@code DocumentStoreException} + * this method returns the given {@code Throwable} as is, otherwise it will + * be used as the cause of the returned {@code DocumentStoreException}. + * The {@code ids} will be appended to the given {@code message} and used + * for the returned {@code DocumentStoreException}. + * + * @param message a message for the {@code DocumentStoreException}. + * @param t a {@code Throwable}. + * @param type the type of this exception. + * @param ids a list of {@code DocumentStore} IDs associated with the + * operation that triggered this exception. + * @return a {@link Type#GENERIC} DocumentStoreException. + */ + public static DocumentStoreException asDocumentStoreException(String message, + Throwable t, + Type type, + Iterable ids) { + String msg = message; + if (ids.iterator().hasNext()) { + msg += " " + Lists.newArrayList(ids); + } if (t instanceof DocumentStoreException) { return (DocumentStoreException) t; } else { - return new DocumentStoreException(msg, t); + return new DocumentStoreException(msg, t, type); } } - public static DocumentStoreException convert(Throwable t, - Iterable ids) { - String msg = t.getMessage() + " " + Lists.newArrayList(ids); - return convert(t, msg); + /** + * @return the type of this exception. + */ + public Type getType() { + return type; } + + @CheckForNull + private static String getMessage(Throwable t) { + return t == null ? null : t.toString(); + } }