Есть ли способ Throwable.printStackTrace(PrintStream s)
распечатать полную трассировку стека, чтобы я мог видеть за последней строкой "... 40 more"
?
Есть ли способ Throwable.printStackTrace(PrintStream s)
распечатать полную трассировку стека, чтобы я мог видеть за последней строкой "... 40 more"
?
Ответы:
Вам не нужно; эта информация присутствует в другом месте трассировки стека. Из документов printStackTrace()
:
Обратите внимание на наличие строк, содержащих символы
"..."
. Эти строки показывают, что оставшаяся часть трассировки стека для этого исключения совпадает с указанным количеством кадров из нижней части трассировки стека для исключения, которое было вызвано этим исключением («включающее» исключение).Это сокращение может значительно сократить длину вывода в общем случае, когда обернутое исключение генерируется тем же методом, что и "причинное исключение".
Другими словами, "... x more"
единственный появляется в цепочке исключения и только тогда, когда последние x
строки трассировки стека уже присутствуют как часть трассировки стека другого цепочечного исключения.
Предположим, что метод перехватывает исключение Foo, помещает его в исключение Bar и генерирует Bar. Тогда трассировка стека Foo будет сокращена. Если вам по какой-то причине нужна полная трассировка, все, что вам нужно сделать, это взять последнюю строку перед ...
трассировкой стека Foo и найти ее в трассировке стека Bar; все, что ниже этой строки, - это именно то, что было бы напечатано в трассировке стека Foo.
Возьмем трассировку стека из документации Throwable.printStackTrace () :
HighLevelException: MidLevelException: LowLevelException
at Junk.a(Junk.java:13)
at Junk.main(Junk.java:4)
Caused by: MidLevelException: LowLevelException
at Junk.c(Junk.java:23)
at Junk.b(Junk.java:17)
at Junk.a(Junk.java:11)
... 1 more
Caused by: LowLevelException
at Junk.e(Junk.java:30)
at Junk.d(Junk.java:27)
at Junk.c(Junk.java:21)
... 3 more
Причины отображаются от самой вложенной внизу («основная причина») до той, которой принадлежит напечатанная трассировка стека.
В этом случае первопричина заключается в том LowLevelException
, что вызвало MidLevelException
, что вызвало HighLevelException
.
Чтобы получить полную трассировку стека, вы должны посмотреть кадры включающего исключения (и его включающих исключений):
Поэтому, если бы мы хотели получить полную трассировку стека, LowLevelException
мы бы сделали следующее:
MidLevelException
)
MidLevelException
( HighLevelException
)Тогда ваша полная трассировка стека будет выглядеть так:
LowLevelException
at Junk.e(Junk.java:30)
at Junk.d(Junk.java:27)
at Junk.c(Junk.java:21)
// From MidLevelException stack trace
at Junk.b(Junk.java:17)
at Junk.a(Junk.java:11)
// From HighLevelException stack trace
at Junk.main(Junk.java:4)
Боковые примечания:
Могут быть случаи, когда в списке нет фреймов, например:
HighLevelException: MidLevelException
at Junk.main(Junk.java:4)
Caused by: MidLevelException
... 1 more
Это может произойти , когда причина его создается в той же строке: new HighLevelException(new MidLevelException())
. Не запутайтесь, подход, описанный выше, все еще работает, просто нет фреймов для использования из исключения, продолжайте с его охватывающим.
В некоторых случаях вы можете сохранить подсчет, посмотрев на первый кадр, который не был пропущен (строка выше ... X more
). Если вы знаете, какие методы вызывают метод в этой строке, вы можете напрямую искать вызывающих в кадрах включающего исключения:
HighLevelException: MidLevelException: LowLevelException
at Junk.c(Junk.java:29)
at Junk.b(Junk.java:21)
at Junk.a(Junk.java:13)
at Junk.main(Junk.java:4)
Caused by: MidLevelException
// You know Junk.d is only called by Junk.b
at Junk.d(Junk.java:35)
... 3 more
...
- это первый отличающийся кадр. Однако он, по крайней мере, будет в том же классе, который помогает его найти.