From a60837550e7bd32fc0156daf4b95dab6c0cc6646 Mon Sep 17 00:00:00 2001
From: Tyler Goodlet <jgbt@protonmail.com>
Date: Fri, 10 Jan 2025 12:42:23 -0500
Subject: [PATCH] Yield a boxed-maybe-error from `open_crash_handler()`

Along the lines of something like `pytest.raises()` where the handled
exception can be inspected from the `pdbp` REPL using its `.value` field
B)

This is super handy in particular for understanding
`BaseException[Group]`s without manually adding surrounding handler code
to assign the `except[*] Exception as exc_var:` particularly when trying
to understand multi-cancelled eg trees.
---
 tractor/devx/_debug.py | 24 +++++++++++++++++++-----
 1 file changed, 19 insertions(+), 5 deletions(-)

diff --git a/tractor/devx/_debug.py b/tractor/devx/_debug.py
index 7c178ab1..04df000f 100644
--- a/tractor/devx/_debug.py
+++ b/tractor/devx/_debug.py
@@ -317,6 +317,7 @@ class Lock:
         we_released: bool = False
         ctx_in_debug: Context|None = cls.ctx_in_debug
         repl_task: Task|Thread|None = DebugStatus.repl_task
+        message: str = ''
 
         try:
             if not DebugStatus.is_main_trio_thread():
@@ -444,7 +445,10 @@ class Lock:
                         f'|_{repl_task}\n'
                     )
 
-            log.devx(message)
+            if message:
+                log.devx(message)
+            else:
+                import pdbp; pdbp.set_trace()
 
         return we_released
 
@@ -3168,7 +3172,7 @@ async def maybe_wait_for_debugger(
 @cm
 def open_crash_handler(
     catch: set[BaseException] = {
-        Exception,
+        # Exception,
         BaseException,
     },
     ignore: set[BaseException] = {
@@ -3189,10 +3193,20 @@ def open_crash_handler(
     '''
     __tracebackhide__: bool = tb_hide
 
+    class BoxedMaybeException(Struct):
+        value: BaseException|None = None
+
+    # TODO, yield a `outcome.Error`-like boxed type?
+    # -[~] use `outcome.Value/Error` X-> frozen!
+    # -[x] write our own..?
+    # -[ ] consider just wtv is used by `pytest.raises()`?
+    #
+    boxed_maybe_exc = BoxedMaybeException()
     err: BaseException
     try:
-        yield
+        yield boxed_maybe_exc
     except tuple(catch) as err:
+        boxed_maybe_exc.value = err
         if (
             type(err) not in ignore
             and
@@ -3210,13 +3224,13 @@ def open_crash_handler(
                 )
             except bdb.BdbQuit:
                 __tracebackhide__: bool = False
-                raise
+                raise err
 
             # XXX NOTE, `pdbp`'s version seems to lose the up-stack
             # tb-info?
             # pdbp.xpm()
 
-        raise
+        raise err
 
 
 @cm