summary refs log tree commit diff stats
path: root/lib/system/excpt.nim
diff options
context:
space:
mode:
Diffstat (limited to 'lib/system/excpt.nim')
-rw-r--r--lib/system/excpt.nim37
1 files changed, 28 insertions, 9 deletions
diff --git a/lib/system/excpt.nim b/lib/system/excpt.nim
index 096d01845..950981227 100644
--- a/lib/system/excpt.nim
+++ b/lib/system/excpt.nim
@@ -73,12 +73,11 @@ proc popSafePoint {.compilerRtl, inl.} =
   excHandler = excHandler.prev
 
 proc pushCurrentException(e: ref Exception) {.compilerRtl, inl.} =
-  #if e.parent.isNil:
-  #  e.parent = currException
+  e.up = currException
   currException = e
 
 proc popCurrentException {.compilerRtl, inl.} =
-  currException = nil # currException.parent
+  currException = currException.up
 
 # some platforms have native support for stack traces:
 const
@@ -230,6 +229,18 @@ when false:
     pushCurrentException(e)
     c_longjmp(excHandler.context, 1)
 
+var onUnhandledException*: (proc (errorMsg: string) {.
+  nimcall.}) ## set this error \
+  ## handler to override the existing behaviour on an unhandled exception.
+  ## The default is to write a stacktrace to ``stderr`` and then call ``quit(1)``.
+  ## Unstable API.
+
+template unhandled(buf, body) =
+  if onUnhandledException != nil:
+    onUnhandledException($buf)
+  else:
+    body
+
 proc raiseExceptionAux(e: ref Exception) =
   if localRaiseHook != nil:
     if not localRaiseHook(e): return
@@ -260,14 +271,16 @@ proc raiseExceptionAux(e: ref Exception) =
         add(buf, " [")
         add(buf, $e.name)
         add(buf, "]\n")
-        showErrorMessage(buf)
+        unhandled(buf):
+          showErrorMessage(buf)
+          quitOrDebug()
       else:
         # ugly, but avoids heap allocations :-)
-        template xadd(buf, s, slen: expr) =
+        template xadd(buf, s, slen) =
           if L + slen < high(buf):
             copyMem(addr(buf[L]), cstring(s), slen)
             inc L, slen
-        template add(buf, s: expr) =
+        template add(buf, s) =
           xadd(buf, s, s.len)
         var buf: array[0..2000, char]
         var L = 0
@@ -276,8 +289,13 @@ proc raiseExceptionAux(e: ref Exception) =
         add(buf, " [")
         xadd(buf, e.name, e.name.len)
         add(buf, "]\n")
-        showErrorMessage(buf)
-      quitOrDebug()
+        when defined(nimNoArrayToCstringConversion):
+          template tbuf(): untyped = addr buf
+        else:
+          template tbuf(): untyped = buf
+        unhandled(tbuf()):
+          showErrorMessage(tbuf())
+          quitOrDebug()
 
 proc raiseException(e: ref Exception, ename: cstring) {.compilerRtl.} =
   if e.name.isNil: e.name = ename
@@ -373,7 +391,8 @@ when not defined(noSignalHandler):
       GC_enable()
     else:
       var msg: cstring
-      template asgn(y: expr) = msg = y
+      template asgn(y) =
+        msg = y
       processSignal(sign, asgn)
       showErrorMessage(msg)
     when defined(endb): dbgAborting = true