SCI: preserve more stacktrace, e.g. on throw

This commit is contained in:
Michiel Borkent 2022-11-10 21:04:01 +01:00
parent bb84bd357e
commit ac1b16bfc8
5 changed files with 52 additions and 35 deletions

View file

@ -157,7 +157,7 @@
:deps/manifest :deps}
lambdaisland/uri {:git/url "https://github.com/lambdaisland/uri"
:git/sha "ac4f1f9c8e4f45a088db1c6383ce2191c973987c"
:deps/manifest :deps}
:deps/manifest :deps}
clj-commons/fs {:mvn/version "1.6.310"}
postmortem/postmortem {:git/url "https://github.com/athos/Postmortem"
:git/sha "1a29775a3d286f9f6fe3f979c78b6e2bf298d5ba"}}
@ -170,7 +170,8 @@
:test
{:extra-paths ["test"]
:extra-deps {io.github.cognitect-labs/test-runner
{:git/tag "v0.5.0" :git/sha "b3fd0d2"}}
{:git/tag "v0.5.0" :git/sha "b3fd0d2"}
nubank/matcher-combinators {:mvn/version "3.6.0"}}
:main-opts ["-m" "cognitect.test-runner"]
:exec-fn cognitect.test-runner.api/test}
:test-pod

@ -1 +1 @@
Subproject commit f6a31466fdd76d5f74f701c0aa88af52e56f7fd4
Subproject commit be047624edac65c3c648adace291bba38cd1a933

View file

@ -93,7 +93,8 @@
:feature/priority-map
:feature/rrb-vector
{:dependencies [[com.clojure-goes-fast/clj-async-profiler "0.5.0"]
[com.opentable.components/otj-pg-embedded "0.13.3"]]}]
[com.opentable.components/otj-pg-embedded "0.13.3"]
[nubank/matcher-combinators "3.6.0"]]}]
:uberjar {:global-vars {*assert* false}
:jvm-opts ["-Dclojure.compiler.direct-linking=true"
"-Dclojure.spec.skip-macros=true"

2
sci

@ -1 +1 @@
Subproject commit ee6377460bb0e29466a4271f192c8540c9a4ace9
Subproject commit b9f4dff7a69b5ac729427d86c6d457dc56d3bb6b

View file

@ -1,24 +1,29 @@
(ns babashka.error-test
{:clj-kondo/config '{:linters {:unresolved-symbol {:exclude [match?]}}}}
(:require
[babashka.test-utils :as tu]
[clojure.java.io :as io]
[clojure.string :as str]
[clojure.test :as t :refer [deftest is testing]]))
[clojure.test :as t :refer [deftest is testing]]
[matcher-combinators.test]))
(defn multiline-equals [s1 s2]
(let [lines-s1 (str/split-lines s1)
lines-s2 (str/split-lines s2)
max-lines (max (count lines-s1) (count lines-s2))]
(run! (fn [i]
(let [l1 (get lines-s1 i)
l2 (get lines-s2 i)]
(if (and l1 l2)
(is (= l1 l2)
(format "Lines did not match.\nLine: %s\nLeft: %s\nRight: %s"
i (pr-str l1) (pr-str l2)))
(is false (format "Out of lines at line: %s.\nLeft: %s\nRight: %s"
i (pr-str l1) (pr-str l2))))))
(range max-lines))))
(defmacro multiline-equals [s1 s2]
`(let [lines-s1# (str/split-lines ~s1)
lines-s2# (str/split-lines ~s2)
max-lines# (max (count lines-s1#) (count lines-s2#))
lines-s1# (take max-lines# lines-s1#)
lines-s2# (take max-lines# lines-s2#)]
(is (~'match? (map str/trimr lines-s1#) (map str/trimr lines-s2#)))
#_(run! (fn [i]
(let [l1 (get lines-s1 i)
l2 (get lines-s2 i)]
(if (and l1 l2)
(is (= l1 l2)
(format "Lines did not match.\nLine: %s\nLeft: %s\nRight: %s"
i (pr-str l1) (pr-str l2)))
(is false (format "Out of lines at line: %s.\nLeft: %s\nRight: %s"
i (pr-str l1) (pr-str l2))))))
(range max-lines))))
(deftest stacktrace-from-script-test
(try (tu/bb nil (.getPath (io/file "test" "babashka" "scripts" "divide_by_zero.bb")))
@ -122,7 +127,7 @@ Phase: macroexpand
----- Context ------------------------------------------------------------------
1: (defmacro foo [x] (subs nil 1) `(do ~x ~x)) (foo 1)
^---
^---
----- Stack trace --------------------------------------------------------------
clojure.core/subs - <built-in>
@ -140,7 +145,7 @@ Location: <expr>:1:35
----- Context ------------------------------------------------------------------
1: (defmacro foo [x] `(subs nil ~x)) (foo 1)
^---
^---
----- Stack trace --------------------------------------------------------------
clojure.core/subs - <built-in>
@ -156,7 +161,7 @@ Location: <expr>:1:15
----- Context ------------------------------------------------------------------
1: (defn quux [] (subs nil 1)) (defmacro foo [x & xs] `(do (quux) ~x)) (defn bar [] (foo 1)) (bar)
^---
^---
----- Stack trace --------------------------------------------------------------
clojure.core/subs - <built-in>
@ -178,7 +183,11 @@ Location: <expr>:1:27
----- Context ------------------------------------------------------------------
1: (let [d {:zero 0 :one 1}] (throw (ex-info \"some msg\" d)))
^--- some msg")))
^--- some msg
----- Stack trace --------------------------------------------------------------
user - <expr>:1:27
user - <expr>:1:1")))
(testing "output of ordinary Exception"
(let [output (try (tu/bb nil "(throw (Exception. \"some msg\"))")
@ -191,15 +200,19 @@ Location: <expr>:1:1
----- Context ------------------------------------------------------------------
1: (throw (Exception. \"some msg\"))
^--- some msg"))))
^--- some msg
----- Stack trace --------------------------------------------------------------
user - <expr>:1:1"))))
(deftest debug-exception-print-test
(testing "debug mode includes locals and exception data in output"
(let [output (try (tu/bb nil "--debug" "(let [x 1] (/ x 0))")
(is false) ; ensure that exception is thrown and we don't get here
(catch Exception e (ex-message e)))]
(is (str/includes? (tu/normalize output)
"----- Error --------------------------------------------------------------------
(catch Exception e (ex-message e)))
actual-lines (str/split-lines (tu/normalize output))]
(is (match? (take 16 actual-lines)
(str/split-lines "----- Error --------------------------------------------------------------------
Type: java.lang.ArithmeticException
Message: Divide by zero
Location: <expr>:1:12
@ -211,18 +224,21 @@ Location: <expr>:1:12
----- Stack trace --------------------------------------------------------------
clojure.core// - <built-in>
user - <expr>:1:12
user - <expr>:1:1
----- Exception ----------------------------------------------------------------
clojure.lang.ExceptionInfo: Divide by zero
{:type :sci/error, :line 1, :column 12, :message \"Divide by zero\",")))))
clojure.lang.ExceptionInfo: Divide by zero")))
(is (str/includes? (nth actual-lines 16)
"{:type :sci/error, :line 1, :column 12, :message \"Divide by zero\",")))))
(deftest macro-test
(let [output (try (tu/bb nil "--debug" "(defmacro foo [x] (subs nil 1) `(do ~x ~x)) (foo 1)")
(is false)
(catch Exception e (ex-message e)))
output (tu/normalize output)]
(is (str/includes? output
"----- Error --------------------------------------------------------------------
output (tu/normalize output)
actual-lines (str/join "\n" (take 17 (str/split-lines output)))]
(multiline-equals actual-lines
"----- Error --------------------------------------------------------------------
Type: java.lang.NullPointerException
Location: <expr>:1:19
Phase: macroexpand
@ -238,8 +254,7 @@ user/foo - <expr>:1:1
user - <expr>:1:45
----- Exception ----------------------------------------------------------------
clojure.lang.ExceptionInfo: null
{:type :sci/error, :line 1, :column 19"))))
clojure.lang.ExceptionInfo: null")))
(deftest native-stacktrace-test
(let [output (try (tu/bb nil "(merge 1 2 3)")