I'm new to programming, and my boss recently called try-catch statements "garbage" and told me to avoid them completely. That confused me because I thought exceptions were a standard part of error handling in many languages. I understand that try-catch can be abused, but is there a legitimate reason to avoid it altogether? When should exceptions be caught, and when are alternatives such as explicit error returns, Result types, or validation checks better?
4 Answers
Try-catch is not inherently bad; it depends on the language and how you use it. In Java, Python, JavaScript, and similar languages, exceptions are often the standard way for libraries to report failures, so refusing to catch them can leave errors unhandled. The real problems are broad catch blocks, swallowing errors, and using exceptions as ordinary control flow. Catch a specific failure when you know how to recover, log or rethrow it with useful context, and let unexpected failures reach a central handler.
The best next step is to ask your boss what they meant and which alternative your team expects you to use. They may be referring to a specific language, performance concern, or bad pattern such as catching every exception and replacing it with a vague message. Team conventions matter, but a blanket rule that try-catch is always wrong is too broad. Good error handling should make failures visible, preserve useful diagnostic information, clean up resources, and either recover safely or fail clearly.
Your boss may be criticizing exceptions as a design philosophy rather than saying errors should be ignored. Exceptions create control-flow paths that are less visible in the code: a function several calls deep can suddenly unwind the stack and be handled somewhere far away. That can make large systems harder to reason about, and throwing exceptions repeatedly for routine conditions can also be expensive. Languages such as Go encourage returning errors explicitly, while Rust and some other languages use Result-style types. Those approaches make failure part of the function's visible return value.
Even with explicit error returns, external operations can still fail between a check and the operation itself. A file, database, or network request may need to report failure at the moment it is attempted, so pre-checks are not always a replacement for handling errors.
Avoid using exceptions for situations that are expected and easy to test with normal logic. For example, if a missing dictionary key or an invalid input is a normal possibility, validate it directly or return a clear error value. But don't perform a check just to assume the later operation must succeed—another thread or process may change the state in between. In those cases, attempt the operation and handle its failure. The important distinction is expected business logic versus an operation that genuinely can fail unexpectedly.

A completely empty catch block is especially dangerous because it can make the application look healthy while silently losing data or skipping important work.