How to catch and handle multiple exceptions

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
12 messages Options
Reply | Threaded
Open this post in threaded view
|

How to catch and handle multiple exceptions

Tim Mackinnon
Hi - I’m wondering what the best way for handling multiple exceptions is in Pharo?

It seems like we just have on:do: (where on is a single exception?).

However, I think I’ve noticed that you can concatenate exceptions - so DomainError, ZnHttpUnsuccessful - and then pass that to on:

However, I’m not clear on how we then elegantly process the exception if you want to do different things (which is often the case for unrelated exceptions). I am kind of superseded there isn’t on:do:on:do: (although that seems quite ugly).

So I’m curious how you handle different exceptions without having some sort of case statement in the exception handler? Or do you wrap exceptions handlers over top of each other?

Tim
Reply | Threaded
Open this post in threaded view
|

Re: How to catch and handle multiple exceptions

Richard Sargent
Administrator
On Sun, Apr 7, 2019, 12:13 Tim Mackinnon <[hidden email]> wrote:
Hi - I’m wondering what the best way for handling multiple exceptions is in Pharo?

It seems like we just have on:do: (where on is a single exception?).

However, I think I’ve noticed that you can concatenate exceptions - so DomainError, ZnHttpUnsuccessful - and then pass that to on:

However, I’m not clear on how we then elegantly process the exception if you want to do different things (which is often the case for unrelated exceptions). I am kind of superseded there isn’t on:do:on:do: (although that seems quite ugly).

So I’m curious how you handle different exceptions without having some sort of case statement in the exception handler? Or do you wrap exceptions handlers over top of each other?

This last one.

[[self run]
    on: TestFailure
    do: [:testEx | ...]]
        on: Error
        do: [:error | ...]


Tim
Reply | Threaded
Open this post in threaded view
|

Re: How to catch and handle multiple exceptions

Tim Mackinnon

Thanks, I guess that makes sense, although it somehow looks a bit ugly with the nested brackets.. but nothing else springs to mind so maybe I’ll get used to it (and In my case I think it’s likely 2 or 3 different exceptions)

Tim

Sent from my iPhone

> On 7 Apr 2019, at 20:43, Richard Sargent <[hidden email]> wrote:
>
>
> This last one.
>
> [[self run]
>     on: TestFailure
>     do: [:testEx | ...]]
>         on: Error
>         do: [:error | ...]


Reply | Threaded
Open this post in threaded view
|

Re: How to catch and handle multiple exceptions

Stephan Eggermont-3
Tim Mackinnon <[hidden email]> wrote:
>
> Thanks, I guess that makes sense, although it somehow looks a bit ugly
> with the nested brackets.. but nothing else springs to mind so maybe I’ll
> get used to it (and In my case I think it’s likely 2 or 3 different exceptions)

I think I prefer them to be somehow ugly. I don’t want to encourage you to
nest and chain exceptions 😀

Stephan


Reply | Threaded
Open this post in threaded view
|

Re: How to catch and handle multiple exceptions

Sean P. DeNigris
Administrator
In reply to this post by Tim Mackinnon
Tim Mackinnon wrote
> nothing else springs to mind

Double dispatch w extension methods on the Exception classes?



-----
Cheers,
Sean
--
Sent from: http://forum.world.st/Pharo-Smalltalk-Users-f1310670.html

Cheers,
Sean
Reply | Threaded
Open this post in threaded view
|

Re: How to catch and handle multiple exceptions

Sean P. DeNigris
Administrator
Or I guess you don't even need dd here, just #handleMyErrorCase
polymorphically



-----
Cheers,
Sean
--
Sent from: http://forum.world.st/Pharo-Smalltalk-Users-f1310670.html

Cheers,
Sean
Reply | Threaded
Open this post in threaded view
|

Re: How to catch and handle multiple exceptions

Richard O'Keefe
In reply to this post by Tim Mackinnon
VisualAge Smalltalk has, in addition to the standard #on:do:,
#when:do:, ..., #when:do:#when:do:#when:do:#when:do:#when:do:,
with the last four mapping to #whenOneOf:doMatching:, taking
two arrays.

It's easy enough to add your own methods like
on: exn1 do: act1 on: exn2 do: act2
    "An imperfect emulation of VAST's #when:do:when:do:"
    ^[self on: exn1 do: act1] on: exn2 do: act2

on: exn1 do: act1 on: exn2 do: act2 on: exn3 do: act3
    "An imperfect emulation of VAST's #when:do:when:do:when:do:"
    ^[[self on: exn1 do: act1] on: exn2 do: act2] on: exn3 do: act3
to BlockClosure.  It won't be fast, but your code might be
clearer.


On Mon, 8 Apr 2019 at 10:21, Tim Mackinnon <[hidden email]> wrote:

Thanks, I guess that makes sense, although it somehow looks a bit ugly with the nested brackets.. but nothing else springs to mind so maybe I’ll get used to it (and In my case I think it’s likely 2 or 3 different exceptions)

Tim

Sent from my iPhone

> On 7 Apr 2019, at 20:43, Richard Sargent <[hidden email]> wrote:
>
>
> This last one.
>
> [[self run]
>     on: TestFailure
>     do: [:testEx | ...]]
>         on: Error
>         do: [:error | ...]


Reply | Threaded
Open this post in threaded view
|

Re: How to catch and handle multiple exceptions

Esteban A. Maringolo
Richard,

I was going to comment the #when:do:[when:do:] approach of VAST [1].

Why do you say it won't be fast? Because of the multiple exception
handlers in the call stack?

I think that some construct might be used to obtain the same as the
#when:do:when:do: but using a chained approach instead.

Regards,

[1] AFAIR when I used VAST (+a decade ago) it didn't have "ANSI" exceptions.

Esteban A. Maringolo

El lun., 8 abr. 2019 a las 0:49, Richard O'Keefe (<[hidden email]>) escribió:

>
> VisualAge Smalltalk has, in addition to the standard #on:do:,
> #when:do:, ..., #when:do:#when:do:#when:do:#when:do:#when:do:,
> with the last four mapping to #whenOneOf:doMatching:, taking
> two arrays.
>
> It's easy enough to add your own methods like
> on: exn1 do: act1 on: exn2 do: act2
>     "An imperfect emulation of VAST's #when:do:when:do:"
>     ^[self on: exn1 do: act1] on: exn2 do: act2
>
> on: exn1 do: act1 on: exn2 do: act2 on: exn3 do: act3
>     "An imperfect emulation of VAST's #when:do:when:do:when:do:"
>     ^[[self on: exn1 do: act1] on: exn2 do: act2] on: exn3 do: act3
> to BlockClosure.  It won't be fast, but your code might be
> clearer.
>
>
> On Mon, 8 Apr 2019 at 10:21, Tim Mackinnon <[hidden email]> wrote:
>>
>>
>> Thanks, I guess that makes sense, although it somehow looks a bit ugly with the nested brackets.. but nothing else springs to mind so maybe I’ll get used to it (and In my case I think it’s likely 2 or 3 different exceptions)
>>
>> Tim
>>
>> Sent from my iPhone
>>
>> > On 7 Apr 2019, at 20:43, Richard Sargent <[hidden email]> wrote:
>> >
>> >
>> > This last one.
>> >
>> > [[self run]
>> >     on: TestFailure
>> >     do: [:testEx | ...]]
>> >         on: Error
>> >         do: [:error | ...]
>>
>>

Reply | Threaded
Open this post in threaded view
|

Re: How to catch and handle multiple exceptions

Tim Mackinnon
In reply to this post by Richard O'Keefe
Thanks Richard - indeed it was that VisualAge Smalltalk pattern that I was remembering and looking for in Pharo, and was a bit surprised it wasn’t there - and hence thought there’re was possibly a different way.

 I might propose we add this, if no-one else comes up with a better alternative. Handling both application and http exceptions is quite a common pattern - and you don’t always want to do the same blanket thing.

Tim


Sent from my iPhone

On 8 Apr 2019, at 04:48, Richard O'Keefe <[hidden email]> wrote:

VisualAge Smalltalk has, in addition to the standard #on:do:,
#when:do:, ..., #when:do:#when:do:#when:do:#when:do:#when:do:,
with the last four mapping to #whenOneOf:doMatching:, taking
two arrays.

It's easy enough to add your own methods like
on: exn1 do: act1 on: exn2 do: act2
    "An imperfect emulation of VAST's #when:do:when:do:"
    ^[self on: exn1 do: act1] on: exn2 do: act2

on: exn1 do: act1 on: exn2 do: act2 on: exn3 do: act3
    "An imperfect emulation of VAST's #when:do:when:do:when:do:"
    ^[[self on: exn1 do: act1] on: exn2 do: act2] on: exn3 do: act3
to BlockClosure.  It won't be fast, but your code might be
clearer.


On Mon, 8 Apr 2019 at 10:21, Tim Mackinnon <[hidden email]> wrote:

Thanks, I guess that makes sense, although it somehow looks a bit ugly with the nested brackets.. but nothing else springs to mind so maybe I’ll get used to it (and In my case I think it’s likely 2 or 3 different exceptions)

Tim

Sent from my iPhone

> On 7 Apr 2019, at 20:43, Richard Sargent <[hidden email]> wrote:
>
>
> This last one.
>
> [[self run]
>     on: TestFailure
>     do: [:testEx | ...]]
>         on: Error
>         do: [:error | ...]


Reply | Threaded
Open this post in threaded view
|

Re: How to catch and handle multiple exceptions

Richard O'Keefe
In reply to this post by Esteban A. Maringolo
It won't be fast because it creates multiple blocks,
whereas a "native" version would not.
To be honest I have not implemented exceptions in my
Smalltalk yet, but I want to inline []on:do: constructions.
The VAST system I have is 8.6.3, and it supports ANSI
Exceptions.

On Tue, 9 Apr 2019 at 00:31, Esteban Maringolo <[hidden email]> wrote:
Richard,

I was going to comment the #when:do:[when:do:] approach of VAST [1].

Why do you say it won't be fast? Because of the multiple exception
handlers in the call stack?

I think that some construct might be used to obtain the same as the
#when:do:when:do: but using a chained approach instead.

Regards,

[1] AFAIR when I used VAST (+a decade ago) it didn't have "ANSI" exceptions.

Esteban A. Maringolo

El lun., 8 abr. 2019 a las 0:49, Richard O'Keefe (<[hidden email]>) escribió:
>
> VisualAge Smalltalk has, in addition to the standard #on:do:,
> #when:do:, ..., #when:do:#when:do:#when:do:#when:do:#when:do:,
> with the last four mapping to #whenOneOf:doMatching:, taking
> two arrays.
>
> It's easy enough to add your own methods like
> on: exn1 do: act1 on: exn2 do: act2
>     "An imperfect emulation of VAST's #when:do:when:do:"
>     ^[self on: exn1 do: act1] on: exn2 do: act2
>
> on: exn1 do: act1 on: exn2 do: act2 on: exn3 do: act3
>     "An imperfect emulation of VAST's #when:do:when:do:when:do:"
>     ^[[self on: exn1 do: act1] on: exn2 do: act2] on: exn3 do: act3
> to BlockClosure.  It won't be fast, but your code might be
> clearer.
>
>
> On Mon, 8 Apr 2019 at 10:21, Tim Mackinnon <[hidden email]> wrote:
>>
>>
>> Thanks, I guess that makes sense, although it somehow looks a bit ugly with the nested brackets.. but nothing else springs to mind so maybe I’ll get used to it (and In my case I think it’s likely 2 or 3 different exceptions)
>>
>> Tim
>>
>> Sent from my iPhone
>>
>> > On 7 Apr 2019, at 20:43, Richard Sargent <[hidden email]> wrote:
>> >
>> >
>> > This last one.
>> >
>> > [[self run]
>> >     on: TestFailure
>> >     do: [:testEx | ...]]
>> >         on: Error
>> >         do: [:error | ...]
>>
>>

Reply | Threaded
Open this post in threaded view
|

Re: How to catch and handle multiple exceptions

jtuchel
Am 08.04.19 um 14:39 schrieb Richard O'Keefe:

>
> It's easy enough to add your own methods like
> on: exn1 do: act1 on: exn2 do: act2
>     "An imperfect emulation of VAST's #when:do:when:do:"
>     ^[self on: exn1 do: act1] on: exn2 do: act2
>
> on: exn1 do: act1 on: exn2 do: act2 on: exn3 do: act3
>     "An imperfect emulation of VAST's #when:do:when:do:when:do:"
>     ^[[self on: exn1 do: act1] on: exn2 do: act2] on: exn3 do: act3
> to BlockClosure.  It won't be fast, but your code might be
> clearer.

well, an unwanted side effect might be that the handling of exn1 is also guarded by the outer on:do: .

Not that this has to be a problem but it introduces new things to think about when you want to #resignalAs: and such.


-- 
-----------------------------------------------------------------------
Objektfabrik Joachim Tuchel          [hidden email]
Fliederweg 1                         http://www.objektfabrik.de
D-71640 Ludwigsburg                  http://joachimtuchel.wordpress.com
Telefon: +49 7141 56 10 86 0         Fax: +49 7141 56 10 86 1


Reply | Threaded
Open this post in threaded view
|

Re: How to catch and handle multiple exceptions

Esteban A. Maringolo
Maybe the abstraction needed wraps everything within a single handler,
but internally does a switch like statement dispatching to a
particular error handler block.

handledBlock
  exceptionDispatcher
    on: NotFoundError do: [:ex | ...];
    on: MessageNotUnderstood do: [:ex | .. ].

BlockClosure>>exceptionDispatcher

| exceptionDispatcher|
exceptionDispatcher:= ExceptionDispatcher new.
self on: Exception do: [:ex | dispatcher handle: ex ].
^exceptionDispatcher


ExceptionDispatcher>>on: exceptionClass do: aBlock
  self handlers add: exceptionClass -> aBlock

The #exceptionDispatcher method would return this special object that
deals with the resolution of each exception class (how to sort them
would't be trivial unless done naively). But any resignalling would be
only one level deep.

Disclaimer: I just wrote the code as I replied this email, not
guaranteed to work :)


Esteban A. Maringolo

El lun., 8 abr. 2019 a las 10:09, [hidden email]
(<[hidden email]>) escribió:

>
> Am 08.04.19 um 14:39 schrieb Richard O'Keefe:
>
>
>> >
>> > It's easy enough to add your own methods like
>> > on: exn1 do: act1 on: exn2 do: act2
>> >     "An imperfect emulation of VAST's #when:do:when:do:"
>> >     ^[self on: exn1 do: act1] on: exn2 do: act2
>> >
>> > on: exn1 do: act1 on: exn2 do: act2 on: exn3 do: act3
>> >     "An imperfect emulation of VAST's #when:do:when:do:when:do:"
>> >     ^[[self on: exn1 do: act1] on: exn2 do: act2] on: exn3 do: act3
>> > to BlockClosure.  It won't be fast, but your code might be
>> > clearer.
>
> well, an unwanted side effect might be that the handling of exn1 is also guarded by the outer on:do: .
>
> Not that this has to be a problem but it introduces new things to think about when you want to #resignalAs: and such.
>
>
> --
> -----------------------------------------------------------------------
> Objektfabrik Joachim Tuchel          mailto:[hidden email]
> Fliederweg 1                         http://www.objektfabrik.de
> D-71640 Ludwigsburg                  http://joachimtuchel.wordpress.com
> Telefon: +49 7141 56 10 86 0         Fax: +49 7141 56 10 86 1
>
>