Mercurial > hg4j
diff src/org/tmatesoft/hg/core/HgCallbackTargetException.java @ 423:9c9c442b5f2e
Major refactoring of exception handling. Low-level API uses RuntimeExceptions, while checked are left for higher level
author | Artem Tikhomirov <tikhomirov.artem@gmail.com> |
---|---|
date | Fri, 23 Mar 2012 22:51:18 +0100 |
parents | 2747b0723867 |
children | 31a89587eb04 |
line wrap: on
line diff
--- a/src/org/tmatesoft/hg/core/HgCallbackTargetException.java Fri Mar 23 21:26:01 2012 +0100 +++ b/src/org/tmatesoft/hg/core/HgCallbackTargetException.java Fri Mar 23 22:51:18 2012 +0100 @@ -16,26 +16,31 @@ */ package org.tmatesoft.hg.core; +import org.tmatesoft.hg.internal.ExceptionInfo; import org.tmatesoft.hg.util.Path; /** - * Checked exception that indicates errors in client code and tries to supply extra information about the context it occurred in. + * Checked exception that client supplied callback code can use to indicates its own errors. * - * Generally, client need to pass own error information/exceptions from within implementations of the callback methods they supply. + * <p>Generally, client need to pass own error information/exceptions from within implementations of the callback methods they supply. * However, there's no straightforward way to alter throws clause for these methods, and alternatives like generic {@link Exception} or * library's own {@link HgException} are rather obscure. Suggested approach is to wrap whatever exception user code produces with - * {@link RuntimeException} subclass, {@link Wrap}. Then, unwrap and re-throw with checked {@link HgCallbackTargetException}. + * {@link HgCallbackTargetException}, the only checked exception allowed out from a callback. * - * FIXME REVISIT perhaps, shall just throw HgCallbackTargetException from any handler, and do not catch anything in commands at all? - * FIXME decide whether shall root at HgException ("throws HgException, HgCallbackTargetException" looks a bit odd now) + * <p>It's intentionally not a subclass of {@link HgException} to avoid get mixed with library own errors and be processed separately. + * + * FIXME REVISIT shall just throw HgCallbackTargetException from any handler, and do not catch anything in commands at all. * * @author Artem Tikhomirov * @author TMate Software Ltd. */ @SuppressWarnings("serial") -public class HgCallbackTargetException extends HgException { +public class HgCallbackTargetException extends Exception { + + protected final ExceptionInfo<HgCallbackTargetException> details = new ExceptionInfo<HgCallbackTargetException>(this); + /** * @param cause can't be <code>null</code> */ @@ -44,16 +49,11 @@ if (cause == null) { throw new IllegalArgumentException(); } - if (cause.getClass() == Wrap.class) { - // eliminate wrapper - initCause(cause.getCause()); - } else { - initCause(cause); - } + initCause(cause); } @SuppressWarnings("unchecked") - public <T extends Exception> T getTargetException() { + public <T extends Throwable> T getTargetException() { return (T) getCause(); } @@ -64,39 +64,22 @@ @Override public String getMessage() { StringBuilder sb = new StringBuilder(); - sb.append("Original exception thrown: "); + sb.append("Error from callback. Original exception thrown: "); sb.append(getCause().getClass().getName()); sb.append(" at "); - extras.appendDetails(sb); + details.appendDetails(sb); return sb.toString(); } - @Override public HgCallbackTargetException setRevision(Nodeid r) { - return (HgCallbackTargetException) super.setRevision(r); - } - @Override - public HgCallbackTargetException setRevisionIndex(int rev) { - return (HgCallbackTargetException) super.setRevisionIndex(rev); - } - @Override - public HgCallbackTargetException setFileName(Path name) { - return (HgCallbackTargetException) super.setFileName(name); + return details.setRevision(r); } - /** - * Given the approach high-level handlers throw RuntimeExceptions to indicate errors, and - * a need to throw reasonable checked exception from client code, clients may utilize this class - * to get their checked exceptions unwrapped by {@link HgCallbackTargetException} and serve as that - * exception cause, eliminating {@link RuntimeException} mediator. - */ - public static final class Wrap extends RuntimeException { + public HgCallbackTargetException setRevisionIndex(int rev) { + return details.setRevisionIndex(rev); + } - public Wrap(Throwable cause) { - super(cause); - if (cause == null) { - throw new IllegalArgumentException(); - } - } + public HgCallbackTargetException setFileName(Path name) { + return details.setFileName(name); } }