I think this problem could lead to debugger issues with stepOver and
stepThrough. For example:

Context>>#stepToHome:
     ...
     context := aContext insertSender: (Context
          contextOn: UnhandledError do: [:ex | ... ])

It is a method which is used for stepThrough. If current method has outer
handler for Error then the UnhandledError logic will be ignored.

Step over is based on following method:

Context>>runUntilErrorOrReturnFrom: aSender
           ...

context := aSender insertSender: (Context

contextOn: Error do: [:ex |

   error ifNil: [

   "this is ugly but it fixes the side-effects of not sending an Unhandled
error on Halt"

   error := (ex isKindOf: UnhandledError) ifTrue: [ ex exception ] ifFalse:
[ ex ].
...

I think UnhandledError branch will never be true:

[ 1/0 ] on: Error do: [:e | e logCr. e3 pass ]

Handler here is executed only once with ZeroDivide error.
Previous version was based on UnhandledError handler:


context := aSender insertSender: (Context
          contextOn: UnhandledError, Halt do: [:ex | ...]


which had the same issue when there is an outer error handler.
And we have such general error handler (probably introduced in Pharo 6):

WorldMorph>>becomeActiveDuring: aBlock

...

aBlock

on: Error

do: [ :ex | ... ex pass ]


Any UI event is processed under this method.

ср, 18 дек. 2019 г. в 22:31, Denis Kudriashov <[email protected]>:

> 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
>>
>

Reply via email to