How to catch and handle multiple exceptions
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
On Sun, Apr 7, 2019, 12:13 Tim Mackinnon <tim@testit.works> 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
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 <richard.sargent@gemtalksystems.com> wrote:
This last one.
[[self run] on: TestFailure do: [:testEx | ...]] on: Error do: [:error | ...]
Tim Mackinnon <tim@testit.works> 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
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
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
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 <tim@testit.works> 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 < richard.sargent@gemtalksystems.com> wrote:
This last one.
[[self run] on: TestFailure do: [:testEx | ...]] on: Error do: [:error | ...]
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 (<raoknz@gmail.com>) 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 <tim@testit.works> 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 <richard.sargent@gemtalksystems.com> wrote:
This last one.
[[self run] on: TestFailure do: [:testEx | ...]] on: Error do: [:error | ...]
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 <emaringolo@gmail.com> 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 (<raoknz@gmail.com>) 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 <tim@testit.works> 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 <
richard.sargent@gemtalksystems.com> wrote:
This last one.
[[self run] on: TestFailure do: [:testEx | ...]] on: Error do: [:error | ...]
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:jtuchel@objektfabrik.de 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
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, jtuchel@objektfabrik.de (<jtuchel@objektfabrik.de>) 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:jtuchel@objektfabrik.de 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
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 <raoknz@gmail.com> 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 <tim@testit.works> 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 <richard.sargent@gemtalksystems.com> wrote:
This last one.
[[self run] on: TestFailure do: [:testEx | ...]] on: Error do: [:error | ...]
participants (7)
-
Esteban Maringolo -
jtuchel@objektfabrik.de -
Richard O'Keefe -
Richard Sargent -
Sean P. DeNigris -
Stephan Eggermont -
Tim Mackinnon