Programming & Development

Try-Catch Is Garbage? Why Your Boss Might Be Right (And Wrong)

James Miller

James Miller

February 06, 2026

10 min read 31 views

When your boss calls try-catch 'garbage,' they're tapping into a decades-old programming debate. We explore both sides, practical alternatives, and when exceptions actually make sense in modern development.

programming, html, css, javascript, php, website development, code, html code, computer code, coding, digital, computer programming, pc, www

Introduction: When Your Boss Calls Your Code Garbage

You're just trying to write robust code. You add a try-catch block to handle that potential file read error, or maybe that network timeout. Then your boss looks over your shoulder and drops the bomb: "Try-catch is garbage. Don't use it."

Wait, what? This isn't some obscure language feature—it's fundamental error handling in Java, C#, Python, JavaScript, and most modern languages. But here's the thing: your boss isn't entirely wrong, and they're not entirely right either. They're tapping into one of programming's oldest, most heated debates.

I've been on both sides of this argument. I've seen exception handling save applications from crashing in production. I've also seen it create debugging nightmares that took weeks to unravel. Let's unpack what's really going on here.

The Historical Context: Where This "Garbage" Idea Came From

To understand your boss's perspective, we need to go back—way back. Before exceptions became mainstream in the 1990s, programmers handled errors with return codes. Functions would return special values (like -1 or NULL) to indicate something went wrong. You'd check these codes religiously after every operation.

Then exceptions arrived, promising cleaner code. Instead of cluttering your logic with endless error checks, you could handle failures in dedicated catch blocks. The theory was beautiful: separate your happy path from your error handling.

But here's what happened in practice. Developers got lazy. They started wrapping entire functions in giant try-catch blocks, catching generic exceptions, and either swallowing errors silently or logging them without proper context. I've seen codebases where 80% of the logic lived inside try blocks—which completely defeated the purpose.

Your boss has probably been burned by this. They've likely spent nights debugging production issues where exceptions were caught and ignored, or where the stack trace got lost because someone caught Exception instead of IOException. That pain is real.

The Performance Argument: Are Exceptions Really That Slow?

Let's address the elephant in the room: performance. Back in the early 2000s, exceptions were expensive in many languages. Throwing an exception in Java or C++ involved constructing stack traces, unwinding call stacks—heavy operations compared to returning a simple error code.

But here's where 2026 differs from 2006. Modern runtime optimizations have dramatically reduced this cost. In most JVMs and .NET runtimes today, the throwing of exceptions still has overhead, but the presence of try-catch blocks in your code has negligible impact when no exceptions occur.

That said, using exceptions for control flow—like using throw/catch instead of break statements in a loop—is still terrible practice. I once optimized a data processing script that was 40% slower than it should have been because someone thought throwing exceptions to exit loops was "clever." It wasn't.

The real performance issue isn't the mechanism itself—it's how we use it. Exceptions should be exceptional. If you're throwing exceptions for expected conditions (like "user not found" in a lookup function), you're doing it wrong.

The Readability Problem: When Try-Catch Makes Code Worse

coding, programming, css, software development, computer, close up, laptop, data, display, electronics, keyboard, screen, technology, app, program

Here's where your boss might have a legitimate point. Look at this Python code I recently refactored:

try:
    user = get_user_from_db(user_id)
    profile = user.get_profile()
    settings = profile.get_settings()
    value = settings.get("preference")
    processed = process_value(value)
    save_to_cache(processed)
    return processed
except Exception as e:
    logger.error("Something went wrong")
    return None

What's wrong here? Everything. Which line failed? Was it the database call? The profile access? The processing? We have no idea. The stack trace is gone. The error message is useless. And we're returning None, which just pushes the problem downstream.

This pattern—giant try blocks with generic catches—creates what I call "debugging black holes." Errors disappear into them, and you spend hours trying to figure out what actually happened.

Contrast that with Go's approach, where functions return both a result and an error. You have to handle errors immediately, right where they occur. There's no hiding. Your boss might be advocating for something similar—more explicit, local error handling.

The Alternative Universe: Error Codes, Optionals, and Result Types

So if try-catch is "garbage," what should we use instead? Let's explore the alternatives that have gained serious traction by 2026.

Need voice acting?

Characters that resonate on Fiverr

Find Freelancers on Fiverr

First, there's the Rust approach: Result types. Functions return a Result<T, E> that's either a success value or an error. You must explicitly handle both cases. The compiler won't let you ignore errors. This creates incredibly robust code, but with more verbosity.

Then there's the Option/Maybe pattern from functional languages. Instead of throwing exceptions for missing values, you return an Optional that might contain a value or might be empty. This forces you to think about the absence case upfront.

Even in exception-heavy languages, we're seeing patterns shift. In modern C#, you'll see more Try-prefixed methods like TryParse that return bool instead of throwing. In Java, Optional has become standard for methods that might not return a value.

Your boss might be pushing toward these more explicit patterns. And honestly? For many cases, they're right. When failure is an expected outcome (like "file not found" when looking for user uploads), exceptions are the wrong tool.

When Try-Catch Actually Makes Sense (Yes, Really)

Now let's defend try-catch for a moment. Because blanket statements like "never use X" are almost always wrong in programming.

Exceptions shine in specific scenarios. First: unrecoverable errors. When your database connection drops mid-transaction, or when you run out of memory—these are truly exceptional situations where you need to abort and clean up. Try-catch-finally is perfect for this.

Second: boundary layers. At the edges of your system—REST API controllers, UI event handlers, message queue consumers—you want to catch all exceptions, log them with context, and return user-friendly errors. Letting exceptions bubble up to these points and catching them there is actually good practice.

Third: third-party libraries. You can't control whether the library you're using throws exceptions. Wrapping those calls in appropriate try-catch blocks is just responsible programming.

The key is specificity. Instead of catching Exception, catch IOException. Instead of catching RuntimeException, catch IllegalArgumentException. Be as specific as possible, and handle each type appropriately.

A Practical Guide: How to Use Exceptions Without Creating Garbage

code, html, digital, coding, web, programming, computer, technology, internet, design, development, website, web developer, web development

Let's get practical. If you're going to use try-catch (and you probably should in some places), here's how to do it right in 2026.

First, keep your try blocks small. Really small. Ideally, just one operation that can fail. This makes debugging trivial because you know exactly what failed.

Second, catch specific exceptions. If you're reading a file, catch FileNotFoundException and IOException separately. Handle each differently. Only catch Exception at your system boundaries.

Third, never swallow exceptions silently. That empty catch block? That's actual garbage. At minimum, log the exception with enough context to debug it later. Include parameters, user IDs, whatever you need.

Fourth, use finally or try-with-resources for cleanup. If you open a resource in a try block, close it in finally. Modern languages have try-with-resources (Java) or using statements (C#) that handle this automatically.

Here's what good looks like:

try (Connection conn = dataSource.getConnection()) {
    User user = getUser(conn, userId);
    return processUser(user);
} catch (SQLException e) {
    logger.error("Database error for user {}", userId, e);
    throw new ServiceException("Could not load user", e);
} catch (IllegalArgumentException e) {
    logger.warn("Invalid user ID format: {}", userId);
    throw new BadRequestException("Invalid user ID", e);
}

See the difference? Specific catches. Proper logging. Clean resource management. This isn't garbage—this is professional error handling.

Featured Apify Actor

Google Search Results Scraper

Need to see what Google really thinks about your keywords? This actor pulls back the curtain, giving you the raw data fr...

50.6M runs 79.6K users
Try This Actor

What Your Boss Really Means (And How to Respond)

When your boss says "try-catch is garbage," they're probably not speaking literally. They're expressing frustration with bad exception handling patterns they've seen destroy codebases.

What they likely mean is: "Stop using exceptions as a crutch for poor error handling design. Think about where failures can occur and handle them explicitly."

So how do you respond? First, understand their pain points. Ask for examples of where exception handling caused problems in your codebase. Learn what patterns they prefer instead.

Second, propose a middle ground. Maybe your team could adopt rules like:

  • No catching Exception outside of framework layers
  • Try blocks must be no more than 5 lines
  • All exceptions must be logged with context
  • Use Optionals for methods that might not return values

Third, show them modern patterns. Demonstrate how you can use try-with-resources for cleanup. Show how specific exception catching makes debugging easier. Prove that you can use exceptions responsibly.

Remember—your boss wants robust, maintainable code. So do you. You're on the same side. This is just a disagreement about tools.

The Future of Error Handling: What's Coming Next

As we look toward the rest of 2026 and beyond, error handling continues to evolve. A few trends are worth watching.

First, there's growing interest in algebraic effects and typed errors—systems where all possible errors are encoded in the type system. You literally can't forget to handle an error case because the compiler checks it.

Second, observability tools are changing how we handle errors. With distributed tracing and structured logging, catching an exception and logging it with full context (trace IDs, user sessions, etc.) becomes more valuable than trying to handle every error locally.

Third, languages are converging. Java is adding more pattern matching for exceptions. C# continues to refine its exception filters. Even Go is considering some form of try-catch (though they'll never call it that).

The future isn't about eliminating exceptions—it's about making error handling more explicit, more observable, and less surprising.

Conclusion: It's Not Garbage, It's a Tool

So is try-catch garbage? No. It's a tool. And like any tool, it can be used well or poorly.

A hammer isn't garbage because someone used it to break a window. It's a good tool for driving nails, a bad tool for delicate surgery. Try-catch is excellent for handling truly exceptional failures at system boundaries. It's terrible for regular control flow or hiding errors.

Your boss's frustration is understandable—they've seen the bad patterns. But throwing out the entire mechanism is an overcorrection. The real solution is education and better practices.

Next time you write a try-catch block, ask yourself: Is this failure truly exceptional? Am I catching the most specific exception possible? Am I providing enough context for debugging? If you can answer yes to these, you're not writing garbage—you're writing robust, professional code.

And if your boss still insists? Show them this article. Then maybe buy them a coffee and have a real conversation about error handling strategy. Because at the end of the day, we all want the same thing: software that doesn't break in production at 2 AM.

James Miller

James Miller

Cybersecurity researcher covering VPNs, proxies, and online privacy.