Jak przekonwertować ślad stosu na ciąg?

1502

Jaki jest najłatwiejszy sposób przekonwertowania wyniku Throwable.getStackTrace()na ciąg znaków przedstawiający stacktrace?

ripper234
źródło
6
Ponieważ odpowiedź jqno faktycznie używa metody Throwable.getStackTrace () określonej w pytaniu, podczas gdy Brian nie. Zamiast tego używa Throwable.printStackTrace ().
Stijn de Witt
10
Prawie każdy projekt Java powinien zawierać Apache commons-lang. Obejmuje wiele wygodnych metod realizujących niezwykle powszechne potrzeby programistyczne.
Russell Silva,
20
@StijndeWitt Te trzy linie kodu prawie na pewno wymagają faktoringu poza miejscem, w którym je nazwiesz. Ponieważ nie wiesz, gdzie je umieścić, trafią do Twojego zestawu narzędzi wraz ze wszystkimi innymi przydatnymi fragmentami. Bingo! właśnie wymyśliłeś guava / commons-lang / cokolwiek ... tylko nie tak dobrze. Zamiast tego zaimportuj rozsądną bibliotekę narzędzi i oszczędzaj na nowo wymyślając koło. Prawdziwym znakiem nowicjusza jest myślenie, że można wykonać lepszą robotę niż autorzy bibliotek.
Andrew Spencer
6
1. Guava ma - Throwables.getStackTraceAsString (e) 2. Apache Commons Lang - ExceptionUtils.getFullStackTrace 3. Napisz własne metody niestandardowe
user2323036
8
@AndrewSpencer Nie rozumiem, dlaczego tak bardzo staracie się obalić StijndeWitt za to, że chcecie to osiągnąć za pomocą małego fragmentu kodu. Naprawdę nie ma większego niebezpieczeństwa przy pisaniu drobnej metody użytkowej (nie uważam jej za „ARROGANIĘ O SZCZĘŚCIE, oh ​​nieeeee !! myśli, że jest lepszy niż Apache !!”). Istnieje mnóstwo projektów, zwłaszcza w językach JVM innych niż Java, które tak naprawdę nie chcą uwzględniać Guava ani Commons Lang tylko do rejestrowania stosu. Piszę biblioteki Scala i Clojure i na pewno nie uczynię Apache Commons Lang zależnością przechodnią tylko dla jednej metody.
jm0

Odpowiedzi:

1039

Można użyć następującej metody do konwersji Exceptionśledzenia stosu String. Ta klasa jest dostępna w Apache commons-lang, który jest najczęściej zależną biblioteką z wieloma popularnymi otwartymi źródłami

org.apache.commons.lang.exception.ExceptionUtils.getStackTrace(Throwable)

amar
źródło
88
@Stijn - żeby być uczciwym (poniżej napisałem aktualnie najwyższą głosowaną odpowiedź), warto spojrzeć na commons-lang, aby uzyskać o wiele więcej funkcji
Brian Agnew
54
@StijndeWitt Commons Lang jest dość powszechny. Jest już obecny w większości moich projektów / proyectów w pracy.
WhyNotHugo
16
@Hugo dzięki, zamierzałem użyć StringWriter, aby uniknąć dodania nowej biblioteki - okazuje się, że jest to już zależność 3 moich zależności. Resztę sprawdź, czy już go masz.
Nathanial,
33
@MartinAsenov - zgodnie z logiką nigdy nie użyłbyś takiej biblioteki, prawda? Nie użyłbyś go, chyba że już go używasz?
Brian Agnew
16
FYI, pakiet został zmieniony i teraz klasa jest pod adresem: org.apache.commons.lang3.exception.ExceptionUtils.
schmmd
2201

Służy Throwable.printStackTrace(PrintWriter pw)do wysyłania śledzenia stosu do odpowiedniego programu piszącego.

import java.io.StringWriter;
import java.io.PrintWriter;

// ...

StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
e.printStackTrace(pw);
String sStackTrace = sw.toString(); // stack trace as a string
System.out.println(sStackTrace);
Brian Agnew
źródło
505
Jeśli nie lubisz dołączać zewnętrznej biblioteki dla czegoś tak małego i prostego, jak to, skorzystaj z tej odpowiedzi.
Stijn de Witt
8
To przycina ślad stosu, tak samo jak printStackTrace (). Wszystkie wyjątki w stosie są widoczne, ale dla każdego wyjątku stos może zostać przycięty. Każdy, kto wymaga całego śladu, powinien to rozważyć.
Laila Agaev
5
Jak się okazuje, jest to właściwie dokładnie to, co robi metoda Apception ExceptionUtils.getStackTrace (). Właściwie prawie do litery.
ticktock
6
@BrianAgnew, nie powinieneś zamknąć StringWriteri PrintWriter?
Muhammad Gelbana
13
@BrianAgnew, dzięki za odpowiedź. To mnie zainteresowało i oto co znalazłem: stackoverflow.com/questions/14542535/...
Muhammad Gelbana
459

To powinno działać:

StringWriter sw = new StringWriter();
e.printStackTrace(new PrintWriter(sw));
String exceptionAsString = sw.toString();
D. Wróblewski
źródło
69
Zwięzłe w kontekście java jest zawsze zachowana. Że printStackTracepowinien po prostu powrócić ciąg, pozostawiając decyzję, czy wydrukować go lub nie do użytkownika :)
Dmitry
35
printStackTrace drukowanie w konsoli jest dopuszczalne, ale przynajmniej getStackTrace zwracający go jako ciąg znaków powinien być domyślnie dostępny
Mateus Viccari,
5
Jaka część tego jest zwięzła? Musisz skonstruować 2 obiekty, które istnieją wyłącznie w celu umieszczenia śladu stosu w łańcuchu.
ArtOfWarfare
7
@dmitry Wywołana metoda printXXX()powinna wypisać XXX.
user207421,
2
@Greg Właściwie to nie był nawet sarkazm, wymagało jedynie prostego odczytania tego, co powiedział.
Andrew
224

Jeśli tworzysz dla Androida, znacznie łatwiejszym sposobem jest skorzystanie z tego:

import android.util.Log;

String stackTrace = Log.getStackTraceString(exception); 

Format jest taki sam jak getStacktrace, np

09-24 16:09:07.042: I/System.out(4844): java.lang.NullPointerException
09-24 16:09:07.042: I/System.out(4844):   at com.temp.ttscancel.MainActivity.onCreate(MainActivity.java:43)
09-24 16:09:07.042: I/System.out(4844):   at android.app.Activity.performCreate(Activity.java:5248)
09-24 16:09:07.043: I/System.out(4844):   at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1110)
09-24 16:09:07.043: I/System.out(4844):   at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2162)
09-24 16:09:07.043: I/System.out(4844):   at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2257)
09-24 16:09:07.043: I/System.out(4844):   at android.app.ActivityThread.access$800(ActivityThread.java:139)
09-24 16:09:07.043: I/System.out(4844):   at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1210)
09-24 16:09:07.043: I/System.out(4844):   at android.os.Handler.dispatchMessage(Handler.java:102)
09-24 16:09:07.043: I/System.out(4844):   at android.os.Looper.loop(Looper.java:136)
09-24 16:09:07.044: I/System.out(4844):   at android.app.ActivityThread.main(ActivityThread.java:5097)
09-24 16:09:07.044: I/System.out(4844):   at java.lang.reflect.Method.invokeNative(Native Method)
09-24 16:09:07.044: I/System.out(4844):   at java.lang.reflect.Method.invoke(Method.java:515)
09-24 16:09:07.044: I/System.out(4844):   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785)
09-24 16:09:07.044: I/System.out(4844):   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)
Vicky Kapadia
źródło
2
Dzięki. W takim przypadku data i znacznik nie są zapisywane w każdym wierszu, jak w printStackTrace ().
CoolMind
1
W rzeczywistości Log.getStackTraceString w swoim rdzeniu używa wspomnianego wyżej (D. Wróblewskiego) StringWriter i Printwriter.
MikeL
2
Najprostszym sposobem na wydrukowanie go w dzienniku systemu Android jest: Log.e("TAG", "My message", new Throwable());
Erick M. Sprengel
113

OSTRZEŻENIE: Nie zawiera przyczyny (która zwykle jest użytecznym bitem!)

public String stackTraceToString(Throwable e) {
    StringBuilder sb = new StringBuilder();
    for (StackTraceElement element : e.getStackTrace()) {
        sb.append(element.toString());
        sb.append("\n");
    }
    return sb.toString();
}
jqno
źródło
1
Wybrałbym rozszerzenie tego podejścia, jeśli chcesz przyciąć ślad, np. Przekazać parametr maxLines i dodać tylko tyle wierszy do śledzenia
Rich Seller
Brakuje nawiasów po e.getStackTrace. public static String stackTraceToString (wyjątek e) {StringBuilder sb = new StringBuilder (); for (element StackTraceElement: e.getStackTrace ()) {sb.append (element.toString ()); sb.append („<br />”); } return sb.toString (); }
rlc,
2
Nie jestem pewien, ale myślę, że to nie wydrukuje śladu stosu wyjątku przyczyny pierwotnej.
apoorv020
7
Cokolwiek robisz, nie przycinaj śladu. Zdarzyło mi się wiele, wiele razy, że patrzyłem na ślad stosu w dziennikach GlassFish, w którym usunięto przydatne części.
cayhorstmann
Użyj String.format("%n")lub coś podobnego zamiast, "\n"aby uszczęśliwić lamery DOS.
Ceving
89

Dla mnie najczystszym i najłatwiejszym sposobem było:

import java.util.Arrays;
Arrays.toString(e.getStackTrace());
Vladas Diržys
źródło
37
Kod jest czysty, ale wynik nie. Na końcu musisz zrobić .replaceAll („,”, „\ n”). Jednak tracisz wcięcie, które proponuje printStackTrace.
furia
4
Jest to przydatne, gdy logujesz śledzenie w jednym wierszu
webjockey
28
public static String getStackTrace(Throwable t) {
    StringWriter sw = new StringWriter();
    t.printStackTrace(new PrintWriter(sw));
    return sw.toString();
}
Akira Yamamoto
źródło
1
Cześć, chciałbym tylko zaznaczyć, że w cytowanej części odpowiedzi w cytowanej odpowiedzi zaznaczono, że obiekty StringWriteri PrintWriterpowinny być closed .... (lub chyba tylko PrintWritertrzeba je zamknąć, ponieważ zamknięcie powinno również zamknąć StringWriter)
Eric
8
Przez inspirację masz na myśli skopiowane?
Stosujesz
26

Poniższy kod pozwala uzyskać cały stackTrace w Stringformacie bez użycia interfejsów API, takich jak log4J, a nawet java.util.Logger:

catch (Exception e) {
    StackTraceElement[] stack = e.getStackTrace();
    String exception = "";
    for (StackTraceElement s : stack) {
        exception = exception + s.toString() + "\n\t\t";
    }
    System.out.println(exception);
    // then you can send the exception string to a external file.
}
dumonderic
źródło
1
tak, ale to trochę nieporęczne, nie sądzisz? w rozsądnych ramach rejestrowania projektu jest koniecznością, więc po co się martwić
mzzzzb
Ten na początku nie wyświetla komunikatu o błędzie. można jednak dodać
kommradHomer
Możesz użyć StringBuffer zamiast prostej konkatenacji.
dedda1994
Jest to przydatne, gdy nie możesz zarejestrować wiadomości ze względu na prywatność.
A1m
Pamiętaj jednak, że to rozwiązanie nie rejestruje wewnętrznych przyczyn
A1m
19

Oto wersja, którą można skopiować bezpośrednio do kodu:

import java.io.StringWriter; 
import java.io.PrintWriter;

//Two lines of code to get the exception into a StringWriter
StringWriter sw = new StringWriter();
new Throwable().printStackTrace(new PrintWriter(sw));

//And to actually print it
logger.info("Current stack trace is:\n" + sw.toString());

Lub w bloku catch

} catch (Throwable t) {
    StringWriter sw = new StringWriter();
    t.printStackTrace(new PrintWriter(sw));
    logger.info("Current stack trace is:\n" + sw.toString());
}
rubel
źródło
będzie to dalej wykraczać poza zakres obecnej funkcji, tj. gdzie Throwablejest zdefiniowane, prawda?
n611x007
16
Arrays.toString(thrown.getStackTrace())

To najprostszy sposób na przekonwertowanie wyniku na ciąg. Używam tego w moim programie do drukowania śladu stosu

LOGGER.log(Level.SEVERE, "Query Builder Issue Stack Trace : {0} ,Message : {1} objid {2}", new Object[]{Arrays.toString(e.getStackTrace()), e.getMessage(),objId});
Ramanan Durairaj
źródło
Pracował dla mnie, nic nie wygląda na przycinanie! Odpowiedź prostsza niż inna bez żadnej biblioteki zewnętrznej, świetna odpowiedź!
Shaung Cheng
16

Wydrukuj ślad stosu na a PrintStream, a następnie przekonwertuj go na String:

// ...

catch (Exception e)
{
    ByteArrayOutputStream out = new ByteArrayOutputStream(); 
    e.printStackTrace(new PrintStream(out));
    String str = new String(out.toByteArray());

    System.out.println(str);
}
Pieczone Inhalf
źródło
1
to jest najbardziej bezpośrednia odpowiedź
DaSqy Stc
11

Drukowanie śladu stosu na łańcuch

import java.io.PrintWriter;
import java.io.StringWriter;

public class StackTraceUtils {
    public static String stackTraceToString(StackTraceElement[] stackTrace) {
        StringWriter sw = new StringWriter();
        printStackTrace(stackTrace, new PrintWriter(sw));
        return sw.toString();
    }
    public static void printStackTrace(StackTraceElement[] stackTrace, PrintWriter pw) {
        for(StackTraceElement stackTraceEl : stackTrace) {
            pw.println(stackTraceEl);
        }
    }
}

Jest to przydatne, gdy chcesz wydrukować bieżący ślad stosu wątków bez tworzenia instancji Throwable- ale pamiętaj, że tworzenie nowego Throwablei uzyskiwanie śledzenia stosu z tego miejsca jest w rzeczywistości szybsze i tańsze niż wywołanie Thread.getStackTrace.

Jarek Przygódzki
źródło
11

Kotlin

Rozszerzenie klasy Throwable da ci właściwość String error.stackTraceString:

val Throwable.stackTraceString: String
  get() {
    val sw = StringWriter()
    val pw = PrintWriter(sw)
    this.printStackTrace(pw)
    return sw.toString()
  }
vonox7
źródło
10
private String getCurrentStackTraceString() {
    StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
    return Arrays.stream(stackTrace).map(StackTraceElement::toString)
            .collect(Collectors.joining("\n"));
}
eddyrokr
źródło
1
Dziękuję eddyrkokr! Działa idealnie dla wszystkich moich klas. Właśnie dodałem go do podstawowej klasy TestNG i zbiera on stosy jeden po drugim ze wszystkich moich testów!
Krzysztof Walczewski
9

Sprytne strzelanie w pierwszy zestaw komentarzy było bardzo zabawne, ale tak naprawdę zależy od tego, co próbujesz zrobić. Jeśli nie masz jeszcze właściwej biblioteki, to 3 wiersze kodu (jak w odpowiedzi D. Wróblewskiego) są idealne. OTOH, jeśli masz już bibliotekę apache.commons (jak zrobi to większość dużych projektów), to odpowiedź Amara jest krótsza. OK, uzyskanie biblioteki i zainstalowanie jej może zająć dziesięć minut (mniej niż jedna, jeśli wiesz, co robisz). Ale zegar tyka, więc możesz nie mieć czasu do stracenia. Jarek Przygódzki miał ciekawe zastrzeżenie - „Jeśli nie potrzebujesz zagnieżdżonych wyjątków”.

Ale co, jeśli nie potrzebujemy pełnych ślady stosu, zagnieżdżone i wszystkich? W takim przypadku sekret polega na użyciu getFullStackTrace apache.common (patrz http://commons.apache.org/proper/commons-lang/javadocs/api-2.6/org/apache/commons/lang/exception/ExceptionUtils.html # getFullStackTrace% 28java.lang.Throwable% 29 )

Uratowało mi to bekon. Dzięki, Amar, za podpowiedź!

Tihamer
źródło
9

Kod z Apache Commons Lang 3.4 ( JavaDoc ):

public static String getStackTrace(final Throwable throwable) {
    final StringWriter sw = new StringWriter();
    final PrintWriter pw = new PrintWriter(sw, true);
    throwable.printStackTrace(pw);
    return sw.getBuffer().toString();
}

Różnica w porównaniu z innymi odpowiedziami polega na tym, że używa autoFlush on PrintWriter.

IvanRF
źródło
8

Bez java.io.*tego można to zrobić w ten sposób.

String trace = e.toString() + "\n";                     

for (StackTraceElement e1 : e.getStackTrace()) {
    trace += "\t at " + e1.toString() + "\n";
}   

A potem tracezmienna przechowuje ślad stosu. Wyjście zawiera również przyczynę początkową, wyjście jest identyczne zprintStackTrace()

Przykład, printStackTrace()daje:

java.io.FileNotFoundException: / (Is a directory)
    at java.io.FileOutputStream.open0(Native Method)
    at java.io.FileOutputStream.open(FileOutputStream.java:270)
    at java.io.FileOutputStream.<init>(FileOutputStream.java:213)
    at java.io.FileOutputStream.<init>(FileOutputStream.java:101)
    at Test.main(Test.java:9)

traceString posiada, gdy drukowanystdout

java.io.FileNotFoundException: / (Is a directory)
     at java.io.FileOutputStream.open0(Native Method)
     at java.io.FileOutputStream.open(FileOutputStream.java:270)
     at java.io.FileOutputStream.<init>(FileOutputStream.java:213)
     at java.io.FileOutputStream.<init>(FileOutputStream.java:101)
     at Test.main(Test.java:9)
Gala
źródło
5

Wersja Scala

def stackTraceToString(e: Exception): String = {
  import java.io.PrintWriter
  val sw = new StringWriter()
  e.printStackTrace(new PrintWriter(sw))
  sw.toString
}
samthebest
źródło
5

jeśli używasz Java 8, spróbuj tego

Arrays.stream(e.getStackTrace())
                .map(s->s.toString())
                .collect(Collectors.joining("\n"));

kod getStackTrace()funkcji można znaleźć Throwable.javajako:

public StackTraceElement[] getStackTrace() {
    return getOurStackTrace().clone();
}

a dla StackTraceElementdostawców to toString()jako:

public String toString() {
    return getClassName() + "." + methodName +
        (isNativeMethod() ? "(Native Method)" :
         (fileName != null && lineNumber >= 0 ?
          "(" + fileName + ":" + lineNumber + ")" :
          (fileName != null ?  "("+fileName+")" : "(Unknown Source)")));
}

Po prostu dołącz do StackTraceElement„\ n”.

Pengcheng Zhang
źródło
To rozwiązanie nie uwzględnia wcięcia zakładki śledzenia stosu, w przeciwnym razie działa świetnie!
krizajb
4

rozszerzenie odpowiedzi Gali, które obejmie również przyczyny wyjątku:

private String extrapolateStackTrace(Exception ex) {
    Throwable e = ex;
    String trace = e.toString() + "\n";
    for (StackTraceElement e1 : e.getStackTrace()) {
        trace += "\t at " + e1.toString() + "\n";
    }
    while (e.getCause() != null) {
        e = e.getCause();
        trace += "Cause by: " + e.toString() + "\n";
        for (StackTraceElement e1 : e.getStackTrace()) {
            trace += "\t at " + e1.toString() + "\n";
        }
    }
    return trace;
}
len ido
źródło
4

Rozwiązaniem jest konwersja stackTrace tablicy na ciąg danych typu. Zobacz następujący przykład:

import java.util.Arrays;

try{

}catch(Exception ex){
    String stack = Arrays.toString(ex.getStackTrace());
    System.out.println("stack "+ stack);
}
Jorge Santos
źródło
4

Z Java 8 Stream API możesz zrobić coś takiego:

Stream
    .of(throwable.getStackTrace())
    .map(StackTraceElement::toString)
    .collect(Collectors.joining("\n"));

Bierze tablicę elementów śledzenia stosu, konwertuje je na ciąg i łączy w ciąg wielowierszowy.

ivanjermakov
źródło
2
To rozwiązanie usuwa komunikat i ignoruje cały ślad nadrzędny
judovana
3

Mój oneliner do konwersji śledzenia stosu na dołączony ciąg wielu linii:

Stream.of(e.getStackTrace()).map((a) -> a.toString()).collect(Collectors.joining("\n", "[", "]"))

Łatwy do przekazania do rejestratora „jak jest”.

Andrey Lebedenko
źródło
Dostajesz coś, co różni się od tego printStackTrace()tutaj, tracisz: 1) wyjątek, który został zgłoszony; 2) Przyczyny i ich śledzenie stosu
valijon
Różnicy można się spodziewać, ponieważ konwersja printStackTrace()nigdy nie była częścią pytania.
Andrey Lebedenko,
2

Jeśli nie chcesz korzystać z biblioteki zewnętrznej i nie tworzysz aplikacji dla systemu Android , możesz utworzyć metodę „rozszerzenia” w następujący sposób :

public static String getStackTraceString(Throwable e) {
    return getStackTraceString(e, "");
}

private static String getStackTraceString(Throwable e, String indent) {
    StringBuilder sb = new StringBuilder();
    sb.append(e.toString());
    sb.append("\n");

    StackTraceElement[] stack = e.getStackTrace();
    if (stack != null) {
        for (StackTraceElement stackTraceElement : stack) {
            sb.append(indent);
            sb.append("\tat ");
            sb.append(stackTraceElement.toString());
            sb.append("\n");
        }
    }

    Throwable[] suppressedExceptions = e.getSuppressed();
    // Print suppressed exceptions indented one level deeper.
    if (suppressedExceptions != null) {
        for (Throwable throwable : suppressedExceptions) {
            sb.append(indent);
            sb.append("\tSuppressed: ");
            sb.append(getStackTraceString(throwable, indent + "\t"));
        }
    }

    Throwable cause = e.getCause();
    if (cause != null) {
        sb.append(indent);
        sb.append("Caused by: ");
        sb.append(getStackTraceString(cause, indent));
    }

    return sb.toString();
}
Kapé
źródło
2

Stare pytanie, ale chciałbym tylko dodać specjalny przypadek, w którym nie chcesz wydrukować całego stosu , usuwając niektóre części, które tak naprawdę nie są zainteresowane, z wyłączeniem niektórych klas lub pakietów.

Zamiast PrintWriterużycia SelectivePrintWriter:

// This filters out this package and up.
String packageNameToFilter = "org.springframework";

StringWriter sw = new StringWriter();
PrintWriter pw = new SelectivePrintWriter(sw, packageNameToFilter);
e.printStackTrace(pw);
String sStackTrace = sw.toString(); 
System.out.println(sStackTrace);

Jeżeli SelectivePrintWriterklasę podaje:

public class SelectivePrintWriter extends PrintWriter {
    private boolean on = true;
    private static final String AT = "\tat";
    private String internal;

    public SelectivePrintWriter(Writer out, String packageOrClassName) {
        super(out);
        internal = "\tat " + packageOrClassName;
    }

    public void println(Object obj) {
        if (obj instanceof String) {
            String txt = (String) obj;
            if (!txt.startsWith(AT)) on = true;
            else if (txt.startsWith(internal)) on = false;
            if (on) super.println(txt);
        } else {
            super.println(obj);
        }
    }
}

Należy pamiętać, że tę klasę można łatwo dostosować do filtrowania według Regex containslub innych kryteriów. Pamiętaj też, że zależy to od Throwableszczegółów implementacji (prawdopodobnie nie ulegnie zmianie, ale nadal).

MarcG
źródło
1
Tak, działa to dobrze i jest całkiem przydatnym pomysłem.
gil.fernandes
2
 import java.io.PrintWriter;
import java.io.StringWriter;

public class PrintStackTrace {

    public static void main(String[] args) {

        try {
            int division = 0 / 0;
        } catch (ArithmeticException e) {
            StringWriter sw = new StringWriter();
            e.printStackTrace(new PrintWriter(sw));
            String exceptionAsString = sw.toString();
            System.out.println(exceptionAsString);
        }
    }
}

Po uruchomieniu programu wynik będzie podobny:

java.lang.ArithmeticException: / by zero
at PrintStackTrace.main(PrintStackTrace.java:9)
Prakhar Nigam
źródło
1

Zastanawiam się, dlaczego nikt nie wspomniał ExceptionUtils.getStackFrames(exception)

Dla mnie jest to najwygodniejszy sposób na zrzucenie stacktrace ze wszystkimi jego przyczynami do końca:

String.join("\n", ExceptionUtils.getStackFrames(exception));
Andrey Sarul
źródło
0

Ostrzeżenie: to może być trochę nie na temat, ale no cóż ...;)

Nie wiem, jaki był pierwotny powód plakatów, że chciałem, aby ślad stosu był ciągiem. Kiedy ślad stosu powinien skończyć się w dzienniku SLF4J / Logback, ale nie było wyjątku ani nie należy go zgłaszać, oto co robię:

public void remove(List<String> ids) {
    if(ids == null || ids.isEmpty()) {
        LOG.warn(
            "An empty list (or null) was passed to {}.remove(List). " +
            "Clearly, this call is unneccessary, the caller should " + 
            "avoid making it. A stacktrace follows.", 
            getClass().getName(),
            new Throwable ("Stacktrace")
        );

        return;
    }

    // actual work, remove stuff
}

Podoba mi się, ponieważ nie wymaga biblioteki zewnętrznej (innej niż backend logowania, który i tak będzie przez większość czasu na miejscu).

Alexander Wessel
źródło