semantics of Exception>>outer ?

Ned Konz ned at bike-nomad.com
Tue Jul 8 00:42:27 UTC 2003


On Monday 07 July 2003 02:08 am, John W. Sarkela wrote:

> I've been off the list for a while and am currently forging through
> a huge backlog. I have looked forward to see replies to this
> message. I'll not address the ANSI standard as John Brant has
> already pointed out the relevant sections of the spec with a lucid
> example of the distinction between outer and pass.

Hi John,

Thanks for responding.

> ANSI Smalltalk exceptions are *always* handled at some point. All
> exceptions get handled, not all exceptions are recoverable. If the
> exception is unrecoverable, the call chain is curtailed. This is
> the case in which execution is cut short and frames are dropped.
> Note well that this is precisely the case in which the exception
> handler was unable to recover from the exception.

Yes, I understand this.

> Thus, #ifError: should almost certainly be replaced with
> #ifCurtailed:. I can imagine no context in which it makes sense to
> use the selector #ifUnhandledError:. I presume that by unhandled
> error, you intend to distinguish errors for which no handler is
> able to retry or resume.

No. I meant "errors for which the only handler is the default 
handler".

The problem is this: there's lots of places in the existing code where 
an Error of some type is signaled (most often by calling #error:). 
The default handler for this is the familiar one which brings up the 
pre-debug notifier, or logs to a file and terminates Squeak (if there 
is no Debugger class).

Certainly the problem is compounded by the lack of a proper Error 
class hierarchy. So plain Errors are used for everything. This 
includes things like:

- primitives failing
- strings having the wrong format to be converted to Numbers, and 
other parsing errors
- Compilation errors
- HTTP failures

Look at the senders of #error: to see a shockingly large list.

The callers of #ifError: (and #on: Error do: [ ... ] that swallowed 
the Errors) were trying to trap these resumable errors and do 
something reasonable with them -- and to avoid having the outer 
(default) exception handler do something drastic like pop up a 
notifier or terminate Squeak.

Of course, by using those techniques they make it impossible to catch 
errors in an enclosing context.

The *real* fix for this is to make a proper exception hierarchy with 
sensible default actions.

So my change set was a Band-Aid of sorts, intended to add the ability 
to wrap those methods in exception handlers if desired, without 
changing the user interface any. I don't think that (for instance) 
the inability to transfer data from a socket should result in the 
user being presented with a pre-debug window.

If I had changed the callers of #ifError: to call #ifCurtailed: 
instead, we'd suddenly start seeing lots of notifiers.

Contrast the behavior of the following expressions:

[ 'xxx' asNumber ] ifCurtailed: [ 0 ]

(you get a notifier, on which you may hit the Proceed button)

with:

[ 'xxx' asNumber ] ifError: [ 0 ]

(no notifier).

-- 
Ned Konz
http://bike-nomad.com
GPG key ID: BEEA7EFE



More information about the Squeak-dev mailing list