ExceptionUtils.java
/*
* @copyright defined in LICENSE.txt
*/
package hera.util;
import static hera.util.ValidationUtils.assertTrue;
import java.io.PrintWriter;
import java.io.StringWriter;
public class ExceptionUtils {
/**
* Assemble exception message from {@code message} and {@code cause}.
*
* @param message message
* @param cause exception
* @return message to be made
*/
public static String buildExceptionMessage(
final String message,
final Throwable cause) {
if (null == cause) {
return message;
}
final StringBuilder sb = new StringBuilder();
if (null != message) {
sb.append(message).append("; ");
}
sb.append("nested exception is ").append(cause);
return sb.toString();
}
/**
* Print the current thread's stacktrace.
* <p>
* Print stacktrace the upper part from {@link ExceptionUtils#trace()}.
* </p>
*
* @return StackTraceElement's information
*
* @see #trace(StackTraceElement[], int, int)
*/
public static String trace() {
final Thread th = Thread.currentThread();
final StackTraceElement[] elements = th.getStackTrace();
return trace(elements, 2, elements.length);
}
/**
* Print the stacktrace.
* <p>
* return {@code null} if stacktrace is {@code null}
* </P>
*
* @param elements array of {@link StackTraceElement}
*
* @return stacktrace string
*
* @see #trace(StackTraceElement[], int, int)
*/
public static String trace(
final StackTraceElement[] elements) {
if (null == elements) {
return null;
}
return trace(elements, 0, elements.length);
}
/**
* Print the partial stacktrace.
* <p>
* {@code start} is less than {@code end} and both are in a range of {@code elements}.
* return {@code null} if stacktrace is {@code null}
* </p>
*
* @param elements array of {@link StackTraceElement}
* @param start start index
* @param end end index
* @return stacktrace string
*/
public static String trace(
final StackTraceElement[] elements,
final int start,
final int end) {
// Check input
if (null == elements) {
return null;
}
if (start < 0) {
throw new ArrayIndexOutOfBoundsException();
}
if (elements.length < end) {
throw new ArrayIndexOutOfBoundsException();
}
assertTrue(start < end);
// Build the stack trace information.
final StringBuilder buffer = new StringBuilder();
for (int i = start; i < end; ++i) {
buffer.append(elements[i].toString());
buffer.append("\n");
}
return buffer.toString();
}
/**
* Build printable string from {@code e}.
* <p>
* return {@code null} if {@code e} is {@code null}
* </p>
*
* @param e {@link Throwable} to print
* @return information about <code>e</code>
*/
public static String getStackTraceOf(
final Throwable e) {
if (null == e) {
return null;
}
final StringWriter writer = new StringWriter();
final PrintWriter w = new PrintWriter(writer);
e.printStackTrace(w);
return writer.toString();
}
/**
* Concat two stack trace into one. Concated form is {@code leftTrace, rightTrace}.
*
* @param left left track trace
* @param right right stack trace
* @return concated stack trace
*/
public static StackTraceElement[] concat(final StackTraceElement[] left,
final StackTraceElement[] right) {
final StackTraceElement[] ret = new StackTraceElement[left.length + right.length];
System.arraycopy(left, 0, ret, 0, left.length);
System.arraycopy(right, 0, ret, left.length, right.length);
return ret;
}
}