
/*
 * Copyright (C) 2015 Archie L. Cobbs. All rights reserved.
 */

package org.jsimpledb.util;

import com.google.common.base.Preconditions;

/**
 * Utility methods dealing with {@link Throwable}s.
 */
public final class ThrowableUtil {

    private ThrowableUtil() {
    }

    /**
     * Mask a checked exception and throw it as an unchecked exception.
     *
     * @param t any exception
     * @param <T> unchecked exception type
     * @return never
     * @throws T always
     */
    @SuppressWarnings("unchecked")
    public static <T extends Throwable> T maskException(Throwable t) throws T {
        throw (T)t;
    }

    /**
     * Prepend stack frames from the current thread onto the given exception's stack frames.
     *
     * <p>
     * This is used to re-throw an exception created in another thread without losing the stack frame information
     * associated with the current thread.
     *
     * @param t exception from another thread
     * @throws IllegalArgumentException if {@code t} is null
     */
    public static void prependCurrentStackTrace(Throwable t) {
        Preconditions.checkArgument(t != null, "null t");
        final StackTraceElement[] innerFrames = t.getStackTrace();
        final StackTraceElement[] outerFrames = new Throwable().getStackTrace();
        final StackTraceElement[] frames = new StackTraceElement[innerFrames.length + Math.max(outerFrames.length, 0)];
        System.arraycopy(innerFrames, 0, frames, 0, innerFrames.length);
        for (int i = 0; i < outerFrames.length; i++)
            frames[innerFrames.length + i] = outerFrames[i];
        t.setStackTrace(frames);
    }
}


@@ -1098,71 +1098,549 @@
     
-Preconditions.checkArgument(t != null, %22null t%22);%0A
+t.setStackTrace(ThrowableUtil.appendStackFrames(t, new Throwable().getStackTrace()));%0A    %7D%0A%0A    /**%0A     * Prepend stack frames from the current thread onto the given exception's stack frames and return the result.%0A     *%0A     * @param t original exception%0A     * @param outerFrames stack frames that should wrap %7B@code t%7D's stack frames%0A     * @return an array containing %7B@code t%7D's stack frames, followed by %7B@code outerFrames%7D%0A     * @throws IllegalArgumentException if %7B@code t%7D or %7B@code outerFrames%7D is null%0A 
     
+*/%0A
     
-final
+public static
  Sta
@@ -1660,38 +1660,207 @@
 t%5B%5D 
-innerFrames = t.getStackTrace(
+appendStackFrames(Throwable t, StackTraceElement%5B%5D outerFrames) %7B%0A        Preconditions.checkArgument(t != null, %22null t%22);%0A        Preconditions.checkArgument(outerFrames != null, %22null outerFrames%22
 );%0A 
@@ -1884,35 +1884,35 @@
 kTraceElement%5B%5D 
-out
+inn
 erFrames = new T
@@ -1906,31 +1906,17 @@
 rames = 
-new Throwable()
+t
 .getStac
@@ -2015,17 +2015,8 @@
 h + 
-Math.max(
 oute
@@ -2033,12 +2033,8 @@
 ngth
-, 0)
 %5D;%0A 
@@ -2231,31 +2231,21 @@
     
-t.setStackTrace(
+return 
 frames
-)
 ;%0A  

Add ThrowableUtil.appendStackFrames().