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 |
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 |
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 > > |
Free forum by Nabble | Edit this page |