Skip to content

Commit 5cddfe6

Browse files
authored
Update exception parsing for modern JREs
2 parents 2b0108f + c1d6eb0 commit 5cddfe6

File tree

6 files changed

+1702
-18
lines changed

6 files changed

+1702
-18
lines changed

CHANGES.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
1+
## 3.6.6 -- UNRELEASED
2+
3+
Improved `clj-commons.format.exceptions/parse-exception` to deal with exception text changes
4+
in more recent JREs.
5+
6+
[Closed Issues](https://github.com/clj-commons/pretty/milestone/65?closed=1)
7+
18
## 3.6.5 -- 17 Sep 2025
29

310
Add a missing bridge function to io.aviso.repl, `pretty-print-exception`.

deps.edn

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
:aliases
55
{:test
66
;; clj -X:test
7-
{:extra-paths ["test"]
7+
{:extra-paths ["test" "test-resources"]
88
:extra-deps {criterium/criterium {:mvn/version "0.4.6"}
99
org.clojure/core.async {:mvn/version "1.8.741"}
1010
nubank/matcher-combinators {:mvn/version "3.9.2"}

src/clj_commons/format/exceptions.clj

Lines changed: 38 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -773,18 +773,43 @@
773773

774774
(def ^:private re-exception-start
775775
"The start of an exception, possibly the outermost exception."
776-
#"(Caused by: )?(\w+(\.\w+)*): (.*)"
777-
; Group 2 - exception name
778-
; Group 4 - exception message
779-
)
776+
#"(?ix)
777+
(?:caused \s by: \s)?
778+
(\w+(?:\.\w+)*) # Group 1 - exception name
779+
(?:
780+
: \s
781+
(.*))? # Group 2 - exception message (or nil)")
780782

781783
(def ^:private re-stack-frame
782784
;; Sometimes the file name and line number are replaced with "Unknown source"
783-
#"\s+at ([a-zA-Z_.$\d<>]+)\(((.+):(\d+))?.*\).*"
784-
; Group 1 - class and method name
785-
; Group 3 - file name (or nil)
786-
; Group 4 - line number (or nil)
787-
)
785+
#"(?ix)
786+
\s+
787+
at
788+
\s
789+
(?:
790+
[a-z.]+/)? # java.base/ prefix
791+
([a-z_.$\d<>]+) # Group 1 - class and method name
792+
\(
793+
(?:
794+
(?:
795+
(.+) # Group 2 - file name
796+
:
797+
(\d+) # Group 3 - line number
798+
)?
799+
.* # match \"Native Method\" if no file/line
800+
)
801+
\)
802+
.* # Extra text (older JRE JAR and version data?)
803+
")
804+
805+
(def ^:private re-more-frames
806+
#"(?ix)
807+
\s+
808+
\Q...\E
809+
\s+
810+
\d+
811+
\s+
812+
(?:more|\Qcommon frames omitted\E)")
788813

789814
(defn- add-message-text
790815
[exceptions line]
@@ -815,7 +840,7 @@
815840
(defn parse-exception
816841
"Given a chunk of text from an exception report (as with `.printStackTrace`), attempts to
817842
piece together the same information provided by [[analyze-exception]]. The result
818-
is ready to pass to [[write-exception*]].
843+
is ready to pass to [[format-exception*]].
819844
820845
This code does not attempt to recreate properties associated with the exceptions; in most
821846
exception's cases, this is not necessarily written to the output. For clojure.lang.ExceptionInfo,
@@ -844,7 +869,7 @@
844869
(condp = state
845870

846871
:start
847-
(let [[_ _ exception-class-name _ exception-message] (re-matches re-exception-start line)]
872+
(let [[_ exception-class-name exception-message] (re-matches re-exception-start line)]
848873
(when-not exception-class-name
849874
(throw (ex-info "Unable to parse start of exception."
850875
{:line line
@@ -869,7 +894,7 @@
869894
stack-trace-batch))
870895

871896
:stack-frame
872-
(let [[_ class-and-method _ file-name line-number] (re-matches re-stack-frame line)]
897+
(let [[_ class-and-method file-name line-number] (re-matches re-stack-frame line)]
873898
(if class-and-method
874899
(recur :stack-frame
875900
more-lines
@@ -888,7 +913,7 @@
888913
[])))
889914

890915
:skip-more-line
891-
(if (re-matches #"\s+\.\.\. \d+ (more|common frames omitted)" line)
916+
(if (re-matches re-more-frames line)
892917
(recur :start more-lines
893918
exceptions stack-trace stack-trace-batch)
894919
(recur :start lines

0 commit comments

Comments
 (0)