             ::components condition-components}))
 
 #?(:clj
+(defn stack-trace-who
+  "Get a suitable argument for [[&who]] from an exception object."
+  [st]
+  ;; the top is the let, above that it's stack-trace-who itself
+  (if-let [^StackTraceElement e (nth st 2)]
+    (let [class (.getClassName e)
+          method (.getMethodName e)]
+      ;; adapted from clojure.stacktrace
+      (let [match (re-matches #"^([A-Za-z0-9_.-]+)\$(\w+)$" (str class))]
+        (if (and match (= "invoke" method))
+          (apply format "%s/%s" (rest match))
+          (format "%s.%s" class method)))))))
+
+#?(:clj
 (defn ->condition
   "Coerce something into a condition object.
 

(defmacro condition
  [?base ?message & ?irritants]
  `(combine-conditions ~?base
                       (make-who-condition (stack-trace-who))
                       (make-message-condition ~?message)
                       (make-irritants-condition [~@?irritants]))))


   (condition? thing) thing

   (instance? Throwable thing)
   (let [^Throwable throwable thing]
     (make-condition (mapcat condition-components
                             (filter identity
                                     [(make-throwable throwable)
                                      (make-message-condition (.getMessage throwable))
                                      (cond
                                       (instance? Exception throwable) (make-error)
                                       (instance? Error throwable) (make-assertion-violation)
                                       :else nil)
                                      (make-who-condition (stack-trace-who (.getStackTrace throwable)))]))))

   :else (clojure.core/assert (instance? Throwable thing) "not a throwable"))))

