I've always thought try/catch is a very good model.
When you have an error, you have to handle it, or someone up the chain has to, or the program crashes(Or behaves in an undefined way, if it's a language like C that makes it way too easy to ignore return codes).
Try/catch directly expresses all that in a language construct without requiring you to explicitly think about it much, except in functions that throw or functions that catch.
Requiring functions to declare throws fixes most of the issues with it.
When you have an error, you have to handle it, or someone up the chain has to, or the program crashes(Or behaves in an undefined way, if it's a language like C that makes it way too easy to ignore return codes).
Try/catch directly expresses all that in a language construct without requiring you to explicitly think about it much, except in functions that throw or functions that catch.
Requiring functions to declare throws fixes most of the issues with it.