Users of UnhandledError definitely shows that it is a critical bug. For example we rely on UnhandledError in Announcer to ensure that all subscriptions will be processed independently on errors signalled by any of them:
ann := Announcer new. ann when: ValueChanged do: [:ann | 1 logCr. 1/0 ]. ann when: ValueChanged do: [:ann | 2 logCr. 2/0 ]. ann when: ValueChanged do: [:ann | 3 logCr. 3/0 ]. ann announce: ValueChanged new It will show 1, 2, 3 in transcript and open 3 debuggers. Each error is deferred to the background process allowing the delivery to continue: AnnouncementSubscription>>deliver: anAnnouncement " deliver an announcement to receiver. In case of failure, it will be handled in separate process" ^ (self handlesAnnouncement: anAnnouncement ) ifTrue: [ [action cull: anAnnouncement cull: announcer] on: UnhandledError fork: [:ex | ex pass ]] Now if you will try to wrap #announce: into handler block the deliver will be interrupted by first error: [ann announce: ValueChanged new] on: ZeroDivide do: [ :err | err logCr. err pass ]. It will open single debugger at first handler error. ср, 18 дек. 2019 г. в 20:44, Denis Kudriashov <[email protected]>: > Hi. > > I played a bit with exceptions trying to detect that given block will open > the debugger. My idea was to simply catch UnhandledError which normally > means that no outer code handles given error and therefore debugger is > appeared. > For my surprise the following example works from playground but not from > the browser editor: > > > [MyTestError signal ] on: UnhandledError do: [ :e | self halt ] > > > In playground you will see the halt. But from the browser the debugger > will show MyTestError. > > After breaking my head I found that there is a difference how scripts are > executed in those tools. In Playground it is a deferred action. But in the > browser it is evaluated as a deep event processing code (keymap processing) > and there is an outer error handler (on: Error do: ) which does some work > and passes the exception further (err pass). > Following script demonstrates the difference in the error processing logic > when there is an outer handler: > > > [ > > [MyTestError signal ] on: UnhandledError do: [ :e | self halt ] > > ] on: MyTestError do: [ :z | z pass] > > > Try it from playground. Second line separately will show the halt while > all together it will stop at MyTestError signal. > > Debugging shows that when the outer handler is processed it sets the > handler context into the exception and it skips the existing handler for > UnhandledError. > > The question: is it a feature or a bug? > Think also how following code should work (unrelated to UnhandledError > logic): > > [ > > [ 1/0 ] on: MyTestError do: [ :e | self halt ] > > ] on: ZeroDivide do: [ :z | MyTestError signal ] > > > Currently it will show MyTestError signal. > > Best regards, > Denis >
