Exception hanlding while enumerating

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

Exception hanlding while enumerating

Günther Schmidt
Hi,

I still have to figure out how to use ST Exception Handling.

I want to iterate over a collection, but some of the items in the
collection will have invalid data.

So I want to catch the error, but have the "iteration" continue never
the less.


        res := conn query: 'Select * from Buecher'.
        rs := res readStream.
        [rs atEnd]
                whileFalse:
                        [| book next |

                        next := rs next.
                        [book := self bookFromRecord: next] on: ImportException do: [:ex | ex
exit].
                        self addBook: book].

How can I do that?

Günther


Reply | Threaded
Open this post in threaded view
|

Re: Exception hanlding while enumerating

Chris Uppal-3
Günther,

> I want to iterate over a collection, but some of the items in the
> collection will have invalid data.
>
> So I want to catch the error, but have the "iteration" continue never
> the less.

This should do it:

rs do:
    [:next |
        [| book |
        book := self bookFromRecord: next.
        self addBook: book]
            on: ImportException
            do: [:ex | "do nothing" ].
    ].

When an exception is thrown from #bookFromRecord: there is no action to resume
it, or otherwise mess with the flow-of-control, so the whole (inner) block is
just aborted, and #addBook: is never invoked.

Another, less clear (IMO), way of doing essentially the same thing might be
interesting, if only for contrast:

rs do:
    [:next || book |
    book := [self bookFromRecord: next]
                        on: ImportException
                        do: [:ex | ex return: nil].
    book isNil ifFalse: [self addBook: book]].

In this case, instead of just aborting the whole block, we tell the exception
what the value answered by the block should be, and then check for that value
outside the protected block.

There are other options too, but I find that I rarely need them.

    -- chris


Reply | Threaded
Open this post in threaded view
|

Re: Exception hanlding while enumerating

Günther Schmidt
Chris,

thanks,

once again it`s embarrassing to see that the solution is so simple and
so obvious.

There was still this unresolved mystery of using and handling exceptions
as a means of control flow and once again it turns out to be rather simple.

Oh dear!

Günther

Chris Uppal schrieb:

> Günther,
>
>> I want to iterate over a collection, but some of the items in the
>> collection will have invalid data.
>>
>> So I want to catch the error, but have the "iteration" continue never
>> the less.
>
> This should do it:
>
> rs do:
>     [:next |
>         [| book |
>         book := self bookFromRecord: next.
>         self addBook: book]
>             on: ImportException
>             do: [:ex | "do nothing" ].
>     ].
>
> When an exception is thrown from #bookFromRecord: there is no action to resume
> it, or otherwise mess with the flow-of-control, so the whole (inner) block is
> just aborted, and #addBook: is never invoked.
>
> Another, less clear (IMO), way of doing essentially the same thing might be
> interesting, if only for contrast:
>
> rs do:
>     [:next || book |
>     book := [self bookFromRecord: next]
>                         on: ImportException
>                         do: [:ex | ex return: nil].
>     book isNil ifFalse: [self addBook: book]].
>
> In this case, instead of just aborting the whole block, we tell the exception
> what the value answered by the block should be, and then check for that value
> outside the protected block.
>
> There are other options too, but I find that I rarely need them.
>
>     -- chris
>
>