blob: d22d122ad2b231f402acbe1fc4813d33320f9978 [file] [log] [blame]
/*
* Copyright 2000-2013 JetBrains s.r.o.
*
* 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 com.intellij.util;
import com.intellij.openapi.diagnostic.Logger;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.Arrays;
public class ExceptionUtil {
private ExceptionUtil() {
}
public static Throwable getRootCause(Throwable e) {
while (true) {
if (e.getCause() == null) return e;
e = e.getCause();
}
}
public static <T> T findCause(Throwable e, Class<T> klass) {
while (e != null && !klass.isInstance(e)) {
e = e.getCause();
}
return (T)e;
}
public static boolean causedBy(Throwable e, Class klass) {
return findCause(e, klass) != null;
}
@NotNull
public static Throwable makeStackTraceRelative(@NotNull Throwable th, @NotNull Throwable relativeTo) {
StackTraceElement[] trace = th.getStackTrace();
StackTraceElement[] rootTrace = relativeTo.getStackTrace();
for (int i=0, len = Math.min(trace.length, rootTrace.length); i < len; i++) {
if (trace[trace.length - i - 1].equals(rootTrace[rootTrace.length - i - 1])) continue;
int newDepth = trace.length - i;
th.setStackTrace(Arrays.asList(trace).subList(0, newDepth).toArray(new StackTraceElement[newDepth]));
break;
}
return th;
}
@NotNull
public static String getThrowableText(@NotNull Throwable aThrowable) {
StringWriter stringWriter = new StringWriter();
@SuppressWarnings("IOResourceOpenedButNotSafelyClosed")
PrintWriter writer = new PrintWriter(stringWriter);
aThrowable.printStackTrace(writer);
return stringWriter.getBuffer().toString();
}
@NotNull
public static String getThrowableText(@NotNull Throwable aThrowable, @NonNls @NotNull final String stackFrameSkipPattern) {
@NonNls final String prefix = "\tat ";
@NonNls final String prefixProxy = prefix + "$Proxy";
final String prefixRemoteUtil = prefix + "com.intellij.execution.rmi.RemoteUtil";
final String skipPattern = prefix + stackFrameSkipPattern;
final StringWriter stringWriter = new StringWriter();
@SuppressWarnings("IOResourceOpenedButNotSafelyClosed")
final PrintWriter writer = new PrintWriter(stringWriter) {
boolean skipping = false;
@Override
public void println(final String x) {
boolean curSkipping = skipping;
if (x != null) {
if (!skipping && x.startsWith(skipPattern)) curSkipping = true;
else if (skipping && !x.startsWith(prefix)) curSkipping = false;
if (curSkipping && !skipping) {
super.println("\tin "+ stripPackage(x, skipPattern.length()));
}
skipping = curSkipping;
if (skipping) {
skipping = !x.startsWith(prefixRemoteUtil);
return;
}
if (x.startsWith(prefixProxy)) return;
super.println(x);
}
}
};
aThrowable.printStackTrace(writer);
return stringWriter.getBuffer().toString();
}
private static String stripPackage(String x, int offset) {
int idx = offset;
while (idx > 0 && idx < x.length() && !Character.isUpperCase(x.charAt(idx))) {
idx = x.indexOf('.', idx) + 1;
}
return x.substring(Math.max(idx, offset));
}
@NotNull
public static String getUserStackTrace(@NotNull Throwable aThrowable, Logger logger) {
final String result = getThrowableText(aThrowable, "com.intellij.");
if (!result.contains("\n\tat")) {
// no stack frames found
logger.error(aThrowable);
}
return result;
}
@Nullable
public static String getMessage(@NotNull Throwable e) {
String result = e.getMessage();
@NonNls final String exceptionPattern = "Exception: ";
@NonNls final String errorPattern = "Error: ";
while ((result == null || result.contains(exceptionPattern) || result.contains(errorPattern)) && e.getCause() != null) {
e = e.getCause();
result = e.getMessage();
}
if (result != null) {
result = extractMessage(result, exceptionPattern);
result = extractMessage(result, errorPattern);
}
return result;
}
@NotNull
private static String extractMessage(@NotNull String result, @NotNull final String errorPattern) {
if (result.lastIndexOf(errorPattern) >= 0) {
result = result.substring(result.lastIndexOf(errorPattern) + errorPattern.length());
}
return result;
}
}