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 <[email protected]> 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
