5252 " clojure.string" " clojure.template" " clojure.uuid" " clojure.walk" " clojure.xml" " clojure.zip" })
5353
5454(defn- core-class?
55- [class-name]
55+ [^String class-name]
5656 (and (not (nil? class-name))
5757 (or (.startsWith class-name " clojure.lang." )
5858 (contains? core-namespaces (second (re-find #"^([^$]+)\$ " class-name))))))
184184 " Returns an analysis of the phase, error, cause, and location of an error that occurred
185185 based on Throwable data, as returned by Throwable->map. All attributes other than phase
186186 are optional:
187- :clojure.error/phase - keyword phase indicator
187+ :clojure.error/phase - keyword phase indicator, one of:
188+ :read-source :compile-syntax-check :compilation :macro-syntax-check :macroexpansion
189+ :execution :read-eval-result :print-eval-result
188190 :clojure.error/source - file name (no path)
189191 :clojure.error/line - integer line number
190192 :clojure.error/column - integer column number
194196 :clojure.error/spec - explain-data for spec error"
195197 {:added " 1.10" }
196198 [datafied-throwable]
197- (let [{:keys [via trace] } datafied-throwable
199+ (let [{:keys [via trace phase] :or {phase :execution } } datafied-throwable
198200 {:keys [type message data]} (last via)
199201 {:clojure.spec.alpha/keys [problems fn ], :clojure.spec.test.alpha/keys [caller]} data
200202 {:clojure.error/keys [source] :as top-data} (:data (first via))]
201- (case (:clojure.error/phase top-data)
202- (:read-source :compile-syntax-check :compilation :macro-syntax-check :macroexpansion )
203- (cond-> top-data
204- source (assoc :clojure.error/source (file-name source))
205- (#{" NO_SOURCE_FILE" " NO_SOURCE_PATH" } source) (dissoc :clojure.error/source )
206- type (assoc :clojure.error/class type)
207- message (assoc :clojure.error/cause message)
208- problems (assoc :clojure.error/spec data))
209-
210- :print-eval-result
211- (let [[source method file line] (-> trace first)]
203+ (assoc
204+ (case phase
205+ :read-source
206+ (let [{:clojure.error/keys [line column]} data]
207+ (cond-> (merge (-> via second :data ) top-data)
208+ source (assoc :clojure.error/source (file-name source))
209+ (#{" NO_SOURCE_FILE" " NO_SOURCE_PATH" } source) (dissoc :clojure.error/source )
210+ message (assoc :clojure.error/cause message)))
211+
212+ (:compile-syntax-check :compilation :macro-syntax-check :macroexpansion )
212213 (cond-> top-data
213- line (assoc :clojure.error/line line)
214- file (assoc :clojure.error/source file)
215- (and source method) (assoc :clojure.error/symbol (symbol (-> source name) (-> method name demunge)))
214+ source (assoc :clojure.error/source (file-name source))
215+ (#{" NO_SOURCE_FILE" " NO_SOURCE_PATH" } source) (dissoc :clojure.error/source )
216216 type (assoc :clojure.error/class type)
217- message (assoc :clojure.error/cause message)))
218-
219- ; ; execution
220- (let [[source method file line] (->> trace (drop-while #(core-class? (name (first %)))) first)
221- file (first (remove #(or (nil? %) (#{" NO_SOURCE_FILE" " NO_SOURCE_PATH" } %)) [(:file caller) file]))
222- err-line (or (:line caller) line)]
223- (cond-> {:clojure.error/phase :execution
224- :clojure.error/class type}
225- err-line (assoc :clojure.error/line err-line)
226217 message (assoc :clojure.error/cause message)
227- (or fn (and source method)) (assoc :clojure.error/symbol (or fn (symbol (-> source name) (-> method name demunge))))
228- file (assoc :clojure.error/source file)
229- problems (assoc :clojure.error/spec data))))))
218+ problems (assoc :clojure.error/spec data))
219+
220+ (:read-eval-result :print-eval-result )
221+ (let [[source method file line] (-> trace first)]
222+ (cond-> top-data
223+ line (assoc :clojure.error/line line)
224+ file (assoc :clojure.error/source file)
225+ (and source method) (assoc :clojure.error/symbol (symbol (-> source name) (-> method name demunge)))
226+ type (assoc :clojure.error/class type)
227+ message (assoc :clojure.error/cause message)))
228+
229+ :execution
230+ (let [[source method file line] (->> trace (drop-while #(core-class? (name (first %)))) first)
231+ file (first (remove #(or (nil? %) (#{" NO_SOURCE_FILE" " NO_SOURCE_PATH" } %)) [(:file caller) file]))
232+ err-line (or (:line caller) line)]
233+ (cond-> {:clojure.error/class type}
234+ err-line (assoc :clojure.error/line err-line)
235+ message (assoc :clojure.error/cause message)
236+ (or fn (and source method)) (assoc :clojure.error/symbol (or fn (symbol (-> source name) (-> method name demunge))))
237+ file (assoc :clojure.error/source file)
238+ problems (assoc :clojure.error/spec data))))
239+ :clojure.error/phase phase)))
230240
231241(defn ex-str
232242 " Returns a string from exception data, as produced by ex-triage.
273283 loc
274284 cause)
275285
286+ :read-eval-result
287+ (format " Error reading eval result (%s) at %s (%s).%n%s%n" simple-class symbol loc cause)
288+
276289 :print-eval-result
277290 (format " Error printing return value (%s) at %s (%s).%n%s%n" simple-class symbol loc cause)
278291
@@ -380,12 +393,7 @@ by default when a new command-line REPL is started."} repl-requires
380393 input (try
381394 (with-read-known (read request-prompt request-exit))
382395 (catch LispReader$ReaderException e
383- (throw (ex-info
384- (str " Syntax error reading source at (" (.-line e) " :" (.-column e) " )" )
385- {:clojure.error/phase :read-source
386- :clojure.error/line (.-line e)
387- :clojure.error/column (.-column e)}
388- e))))]
396+ (throw (ex-info nil {:clojure.error/phase :read-source } e))))]
389397 (or (#{request-prompt request-exit} input)
390398 (let [value (binding [*read-eval* read-eval] (eval input))]
391399 (set! *3 *2)
@@ -394,9 +402,7 @@ by default when a new command-line REPL is started."} repl-requires
394402 (try
395403 (print value)
396404 (catch Throwable e
397- (throw (ex-info (format " Error printing return value. Cause: " (.getMessage e))
398- {:clojure.error/phase :print-eval-result }
399- e)))))))
405+ (throw (ex-info nil {:clojure.error/phase :print-eval-result } e)))))))
400406 (catch Throwable e
401407 (caught e)
402408 (set! *e e))))]
0 commit comments