234 lines
7.3 KiB
Java
234 lines
7.3 KiB
Java
/*
|
|
* Copyright 2015 Robert von Burg <eitch@eitchnet.ch>
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
package li.strolch.utils.helper;
|
|
|
|
import static li.strolch.utils.helper.StringHelper.isEmpty;
|
|
import static li.strolch.utils.helper.XmlHelper.PROP_LINE_SEPARATOR;
|
|
import static li.strolch.utils.helper.XmlHelper.UNIX_LINE_SEP;
|
|
|
|
import java.io.PrintWriter;
|
|
import java.io.StringWriter;
|
|
|
|
import li.strolch.utils.RemoveCRFilterWriter;
|
|
|
|
/**
|
|
* @author Robert von Burg <eitch@eitchnet.ch>
|
|
*/
|
|
public class ExceptionHelper {
|
|
|
|
/**
|
|
* Returns the class name and method name of the caller
|
|
*
|
|
* @return the class name and method name of the caller
|
|
*/
|
|
public static String getCallerMethod() {
|
|
return getCallerMethod(2);
|
|
}
|
|
|
|
public static String getCallerMethod(int depth) {
|
|
return StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE) //
|
|
.walk(frames -> frames
|
|
.map((StackWalker.StackFrame sf) -> sf.getClassName() + "." + sf.getMethodName())
|
|
.skip(depth)
|
|
.findFirst()).orElse("UnknownClass.unknownMethod!");
|
|
}
|
|
|
|
public static String getCallerMethodNoClass(int depth) {
|
|
return StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE) //
|
|
.walk(frames -> frames.map(StackWalker.StackFrame::getMethodName).skip(depth).findFirst())
|
|
.orElse("UnknownClass.unknownMethod!");
|
|
}
|
|
|
|
/**
|
|
* <p>
|
|
* Returns a message for the given {@link Throwable}
|
|
* </p>
|
|
*
|
|
* <p>
|
|
* A {@link NullPointerException} only has <code>null</code> as the message so this methods returns the class name
|
|
* in such a case
|
|
* </p>
|
|
*
|
|
* @param t the {@link Throwable}
|
|
*
|
|
* @return the exception as string
|
|
*/
|
|
public static String getExceptionMessage(Throwable t) {
|
|
return getExceptionMessage(t, true);
|
|
}
|
|
|
|
/**
|
|
* <p>
|
|
* Returns a message for the given {@link Throwable}
|
|
* </p>
|
|
*
|
|
* <p>
|
|
* A {@link NullPointerException} only has <code>null</code> as the message so this methods returns the class name
|
|
* in such a case
|
|
* </p>
|
|
*
|
|
* @param t the {@link Throwable}
|
|
* @param withClassName if true, then exception class name is prepended to the exception message, if the exception
|
|
* message is null, then this param is ignored
|
|
*
|
|
* @return the exception as string
|
|
*/
|
|
public static String getExceptionMessage(Throwable t, boolean withClassName) {
|
|
if (withClassName || isEmpty(t.getMessage()))
|
|
return t.getClass().getName() + ": " + t.getMessage();
|
|
return t.getMessage();
|
|
}
|
|
|
|
/**
|
|
* <p>
|
|
* Returns a message for the given {@link Throwable}
|
|
* </p>
|
|
*
|
|
* <p>
|
|
* A {@link NullPointerException} only has <code>null</code> as the message so this methods returns the class name
|
|
* in such a case
|
|
* </p>
|
|
*
|
|
* @param t the {@link Throwable}
|
|
*
|
|
* @return the exception as string
|
|
*/
|
|
public static String getExceptionMessageWithCauses(Throwable t) {
|
|
return getExceptionMessageWithCauses(t, true);
|
|
}
|
|
|
|
/**
|
|
* <p>
|
|
* Returns a message for the given {@link Throwable}
|
|
* </p>
|
|
*
|
|
* <p>
|
|
* A {@link NullPointerException} only has <code>null</code> as the message so this methods returns the class name
|
|
* in such a case
|
|
* </p>
|
|
*
|
|
* @param t the {@link Throwable}
|
|
* @param withClassName if true, then exception class name is prepended to the exception message, if the exception
|
|
* message is null, then this param is ignored
|
|
*
|
|
* @return the exception as string
|
|
*/
|
|
public static String getExceptionMessageWithCauses(Throwable t, boolean withClassName) {
|
|
if (t == null)
|
|
return "(null)";
|
|
if (t.getCause() == null)
|
|
return getExceptionMessage(t, withClassName);
|
|
|
|
String root = getExceptionMessageWithCauses(t.getCause(), withClassName);
|
|
return getExceptionMessage(t, withClassName) + "\n" + root;
|
|
}
|
|
|
|
/**
|
|
* Formats the given {@link Throwable}'s stack trace to a string
|
|
*
|
|
* @param t the throwable for which the stack trace is to be formatted to string
|
|
*
|
|
* @return a string representation of the given {@link Throwable}'s stack trace
|
|
*/
|
|
public static String formatException(Throwable t) {
|
|
String ls = System.lineSeparator();
|
|
if (!ls.equals(UNIX_LINE_SEP))
|
|
System.setProperty(PROP_LINE_SEPARATOR, UNIX_LINE_SEP);
|
|
try {
|
|
StringWriter stringWriter = new StringWriter();
|
|
PrintWriter writer = new PrintWriter(new RemoveCRFilterWriter(stringWriter));
|
|
t.printStackTrace(writer);
|
|
return stringWriter.toString();
|
|
} finally {
|
|
if (!ls.equals(UNIX_LINE_SEP))
|
|
System.setProperty(PROP_LINE_SEPARATOR, ls);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Formats the given {@link Throwable}'s message including causes to a string
|
|
*
|
|
* @param t the throwable for which the messages are to be formatted to a string
|
|
*
|
|
* @return a string representation of the given {@link Throwable}'s messages including causes
|
|
*/
|
|
public static String formatExceptionMessage(Throwable t) {
|
|
return formatExceptionMessage(t, true);
|
|
}
|
|
|
|
/**
|
|
* Formats the given {@link Throwable}'s message including causes to a string
|
|
*
|
|
* @param t the throwable for which the messages are to be formatted to a string
|
|
* @param withClassName if true, then exception class name is prepended to the exception message, if the exception
|
|
* message is null, * then this param is ignored
|
|
*
|
|
* @return a string representation of the given {@link Throwable}'s messages including causes
|
|
*/
|
|
public static String formatExceptionMessage(Throwable t, boolean withClassName) {
|
|
if (t.getCause() == null)
|
|
return getExceptionMessage(t, withClassName);
|
|
|
|
String root = formatExceptionMessage(t.getCause(), withClassName);
|
|
return getExceptionMessage(t, withClassName) + "\ncause: " + root;
|
|
}
|
|
|
|
/**
|
|
* Returns the root cause for the given {@link Throwable}
|
|
*
|
|
* @param throwable the {@link Throwable} for which to get the root cause
|
|
*
|
|
* @return the root cause of the given {@link Throwable}
|
|
*/
|
|
public static Throwable getRootCause(Throwable throwable) {
|
|
Throwable t = throwable;
|
|
while (t.getCause() != null) {
|
|
t = t.getCause();
|
|
}
|
|
|
|
return t;
|
|
}
|
|
|
|
/**
|
|
* Returns {@link #getExceptionMessage(Throwable, boolean)} for the root cause of the given {@link Throwable}
|
|
*
|
|
* @param throwable the throwable for which to get the message of the root cause
|
|
*
|
|
* @return {@link #getExceptionMessage(Throwable, boolean)} for the root cause of the given {@link Throwable}
|
|
*/
|
|
public static String getRootCauseMessage(Throwable throwable) {
|
|
return getExceptionMessage(getRootCause(throwable), true);
|
|
}
|
|
|
|
/**
|
|
* Walks the causes for the given {@link Throwable} and sees if the given cause exists
|
|
*
|
|
* @param throwable the {@link Throwable} for which to find the given cause type
|
|
*
|
|
* @return true if the cause was found, false if not
|
|
*/
|
|
public static boolean hasCause(Throwable throwable, Class<? extends Throwable> causeType) {
|
|
Throwable t = throwable;
|
|
while (t != null) {
|
|
if (t.getClass() == causeType)
|
|
return true;
|
|
t = t.getCause();
|
|
}
|
|
|
|
return false;
|
|
}
|
|
}
|