Hi Denis, Thanks very much for the clarification in your previous email (which I haven't quoted here), I did indeed misunderstand the point you were making. On Thu, 19 Dec 2019 at 19:40, Denis Kudriashov <dionisiydk@gmail.com> wrote:
The solution to problem is to resignal UnhandledError instead of simple signalling. Resignal uses original signalContext as a starting point for handlers lookup:
UnhandledError>>signalForException: anError
^anError resignalAs: (self new
exception: anError;
yourself)
I played with some of debugger issues and this code really fixes them. For example try debug following script in playground:
[ self methodWithError ] on: Error do: [ :e | e logCr. e pass ]
With error method:
Object>>methodWithError
1/0
Step into #methodWithError and then stepThrough "1/0". In current image it will hands for a while and then it will open another debugger with single error item. The current debugger process will be broken. Now try to apply proposed change for UnhandledError>>signalForException: and repeat experiment. StepThrough "1/0" will move debugger to ZeroDivide signal showing correct stack.
Confirmed.
Notice that debugging separate "self methodWithError" without outer handler works correctly in both cases. But you should be in clean stack without hidden outer handlers. And in Playground or when you use debugIt it is clean. But you can try in "bad" environment. Execute in browser editor "self halt. self methodWithError". And in debugger just Step Through #methodWithError. It will hangs. Proposed change fixes that.
I will prepare PR with tests. But it would be nice to find other broken places which will be fixed
I thought I'd take a look at VisualWorks (8.3) to see what it does: it has the same behaviour as with your fix above. This opens some other interesting possibilities. Changing some names and reinterpreting your original example: [ result := [ MyResumableError signal ] on: UnhandledError do: [ :e | self doUltimateFallback ] ] on: MyResumableError do: [ :e | e resume: 42 ]. The MyResumableError handler may be way down the call stack. While the code is more than a little contrived, it does demonstrate the possibility of allowing callers to handle exceptions, but then have a fallback if everything else fails. Great detective work! Thanks, Alistair