Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
## 3.6.6 -- UNRELEASED

Improved `clj-commons.format.exceptions/parse-exception` to deal with exception text changes
in more recent JREs.

[Closed Issues](https://github.com/clj-commons/pretty/milestone/65?closed=1)

## 3.6.5 -- 17 Sep 2025

Add a missing bridge function to io.aviso.repl, `pretty-print-exception`.
Expand Down
2 changes: 1 addition & 1 deletion deps.edn
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
:aliases
{:test
;; clj -X:test
{:extra-paths ["test"]
{:extra-paths ["test" "test-resources"]
:extra-deps {criterium/criterium {:mvn/version "0.4.6"}
org.clojure/core.async {:mvn/version "1.8.741"}
nubank/matcher-combinators {:mvn/version "3.9.2"}
Expand Down
51 changes: 38 additions & 13 deletions src/clj_commons/format/exceptions.clj
Original file line number Diff line number Diff line change
Expand Up @@ -773,18 +773,43 @@

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

(def ^:private re-stack-frame
;; Sometimes the file name and line number are replaced with "Unknown source"
#"\s+at ([a-zA-Z_.$\d<>]+)\(((.+):(\d+))?.*\).*"
; Group 1 - class and method name
; Group 3 - file name (or nil)
; Group 4 - line number (or nil)
)
#"(?ix)
\s+
at
\s
(?:
[a-z.]+/)? # java.base/ prefix
([a-z_.$\d<>]+) # Group 1 - class and method name
\(
(?:
(?:
(.+) # Group 2 - file name
:
(\d+) # Group 3 - line number
)?
.* # match \"Native Method\" if no file/line
)
\)
.* # Extra text (older JRE JAR and version data?)
")

(def ^:private re-more-frames
#"(?ix)
\s+
\Q...\E
\s+
\d+
\s+
(?:more|\Qcommon frames omitted\E)")

(defn- add-message-text
[exceptions line]
Expand Down Expand Up @@ -815,7 +840,7 @@
(defn parse-exception
"Given a chunk of text from an exception report (as with `.printStackTrace`), attempts to
piece together the same information provided by [[analyze-exception]]. The result
is ready to pass to [[write-exception*]].
is ready to pass to [[format-exception*]].

This code does not attempt to recreate properties associated with the exceptions; in most
exception's cases, this is not necessarily written to the output. For clojure.lang.ExceptionInfo,
Expand Down Expand Up @@ -844,7 +869,7 @@
(condp = state

:start
(let [[_ _ exception-class-name _ exception-message] (re-matches re-exception-start line)]
(let [[_ exception-class-name exception-message] (re-matches re-exception-start line)]
(when-not exception-class-name
(throw (ex-info "Unable to parse start of exception."
{:line line
Expand All @@ -869,7 +894,7 @@
stack-trace-batch))

:stack-frame
(let [[_ class-and-method _ file-name line-number] (re-matches re-stack-frame line)]
(let [[_ class-and-method file-name line-number] (re-matches re-stack-frame line)]
(if class-and-method
(recur :stack-frame
more-lines
Expand All @@ -888,7 +913,7 @@
[])))

:skip-more-line
(if (re-matches #"\s+\.\.\. \d+ (more|common frames omitted)" line)
(if (re-matches re-more-frames line)
(recur :start more-lines
exceptions stack-trace stack-trace-batch)
(recur :start lines
Expand Down
Loading