/* * Copyright 2000-2010 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 extends Throwable> 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; 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; } }