Generate SSD throwable logging from typed Jerboa

ober

8ce2165555ae67ce4fe42b62bf8dc593705ca468

diff --git a/templates/ssd-review.ss b/templates/ssd-review.ss
index 1a1a676..def03f1 100644
--- a/templates/ssd-review.ss
+++ b/templates/ssd-review.ss
@@ -5998,10 +5998,9 @@
                   (payload : JSONObject)
                   (readTimeoutMillis : Int32)) : Unit
           (kotlin-member-call sendClientLog))
-        (extern (mainActivityThrowableLogFromExceptionRaw
-                  (activity : MainActivity)
+        (extern (throwableLogJsonForExceptionRaw
                   (error : Exception)) : JSONObject
-          (kotlin-member-call throwableLog))
+          (kotlin-call throwableLogJsonForThrowable))
         (extern (mainActivityReviewViewSet
                   (activity : MainActivity)
                   (view : SsdReviewView)) : Unit
@@ -7985,6 +7984,10 @@
             (nullableTextOrEmpty
               (mainActivitySelectedGroupIdRaw activity))
             fields))
+        (def (mainActivityThrowableLogFromExceptionRaw
+               (activity : MainActivity)
+               (error : Exception)) : JSONObject
+          (throwableLogJsonForExceptionRaw error))
         (def (mainActivityLogDetectResultRaw
                (activity : MainActivity)
                (stage : String)
@@ -11081,15 +11084,58 @@
               out)))))
 
     (typed-kotlin-file "com/sfb/ssdreview/ThrowableText.kt"
+      (kotlin-imports (java io PrintWriter)
+                      (java io StringWriter)
+                      (java lang Class)
+                      (org json JSONObject))
       (typed-library (com sfb ssdreview)
-        (export throwableMessageOrEmpty)
+        (export throwableMessageOrEmpty throwableLogJsonForThrowable)
+        (type Class)
+        (type PrintWriter)
+        (type StringWriter)
         (type Throwable)
         (extern (throwableMessage (error : Throwable)) : (Nullable String)
           (kotlin-member-get message))
+        (extern (throwableJavaClassRaw (error : Throwable)) : Class
+          (kotlin-member-get javaClass))
+        (extern (classNameRaw (klass : Class)) : String
+          (kotlin-member-get name))
+        (extern (makeStringWriter) : StringWriter
+          (kotlin-call StringWriter))
+        (extern (makePrintWriter (writer : StringWriter)) : PrintWriter
+          (kotlin-call PrintWriter))
+        (extern (throwablePrintStackTraceRaw
+                  (error : Throwable)
+                  (writer : PrintWriter)) : Unit
+          (kotlin-member-call printStackTrace))
+        (extern (stringWriterToStringRaw
+                  (writer : StringWriter)) : String
+          (kotlin-member-call toString))
+        (extern (throwableLogJsonRaw
+                  (className : String)
+                  (message : String)
+                  (stack : String)) : JSONObject
+          (kotlin-call throwableLogJson))
+        (extern (truncateClientLogStackRaw
+                  (stack : String)) : String
+          (kotlin-call truncateClientLogStack))
+        (type JSONObject)
         (def (throwableMessageOrEmpty (error : (Nullable Throwable))) : String
           (if (nullable-null? error)
             ""
-            (nullableTextOrEmpty (throwableMessage (nullable-get error)))))))
+            (nullableTextOrEmpty (throwableMessage (nullable-get error)))))
+        (def (throwableLogJsonForThrowable
+               (error : Throwable)) : JSONObject
+          (let ((writer (makeStringWriter)))
+            (begin
+              (throwablePrintStackTraceRaw
+                error
+                (makePrintWriter writer))
+              (throwableLogJsonRaw
+                (classNameRaw (throwableJavaClassRaw error))
+                (nullableTextOrEmpty (throwableMessage error))
+                (truncateClientLogStackRaw
+                  (stringWriterToStringRaw writer))))))))
 
     (typed-kotlin-file "com/sfb/ssdreview/EventJson.kt"
       (kotlin-imports (org json JSONObject))
@@ -11402,9 +11448,8 @@
                   (readTimeoutMillis : Int32)) : Unit
           (kotlin-member-call sendClientLog))
         (extern (mainActivityThrowableLogRaw
-                  (activity : MainActivity)
                   (error : Throwable)) : JSONObject
-          (kotlin-member-call throwableLog))
+          (kotlin-call throwableLogJsonForThrowable))
         (def (startCrashSenderThread
                (activity : MainActivity)
                (payload : JSONObject)
@@ -11431,7 +11476,7 @@
               (clientLogCrashFields
                 (nullableTextOrEmpty
                   (nullable-some (threadNameRaw crashingThread)))
-                (mainActivityThrowableLogRaw activity throwable)))
+                (mainActivityThrowableLogRaw throwable)))
             (catch (error : Exception)
               (clientLogFallbackPayload "ssd-uncaught-exception"))))
         (def (sendCrashPayloadBlocking
@@ -12656,14 +12701,6 @@
        "        }"
        "    }"
 	       ""
-	       "    internal fun throwableLog(error: Throwable): JSONObject {"
-       "        val writer = StringWriter()"
-       "        error.printStackTrace(PrintWriter(writer))"
-       "        val stack = writer.toString()"
-       "        val stackText = truncateClientLogStack(stack)"
-       "        return throwableLogJson(error.javaClass.name, nullableTextOrEmpty(error.message), stackText)"
-       "    }"
-	       ""
 	       "}"
        ))
     (typed-kotlin-file "com/sfb/ssdreview/MainActivityConstants.kt"