I can see the author's point, that a throw behaves awfully like a GOTO. It can add complexity and unpredictability to the code path, especially dealing with external modules.
On the other hand, there are situations in which throw/catch provides a simpler, even elegant way to handle errors.
So I'd agree with you that both are useful.
The author makes a good point though, and I will consider it next time whether returning errors may be more suitable, to be clear and explicit/verbose, without requiring the GOTO-like control flow.
If `transform()` threw exceptions, this whole thing aborts. But if it can return an `Error` type, we can continue processing the good ones and log the bad ones (here I ignore them for simplicity).
On the other hand, there are situations in which throw/catch provides a simpler, even elegant way to handle errors.
So I'd agree with you that both are useful.
The author makes a good point though, and I will consider it next time whether returning errors may be more suitable, to be clear and explicit/verbose, without requiring the GOTO-like control flow.