DEV Community

Hari R
Hari R

Posted on

When to use Try-Catch and why too many will hurt me.

I was happily coding a fresh new API endpoint in C# when suddenly memories of past trauma struck: those dreaded QE pings. You know the ones—cryptic async exceptions popping up like surprise horror movie villains, never clearly pointing out their origin and instead blaming innocent methods. Nightmares!

So, naturally, I thought: "Easy fix—throw try-catch blocks everywhere and make my QE happy." But then, reality check—performance.

🔧 First, what really happens when you use try-catch?
“Hey, keep an eye on this block. If anything explodes, don’t crash, just catch it and let me handle it.”

This makes your code safer. But it comes at a cost.
For a more detailed explanation on Try Catch and Throw:
refer -- https://dev.to/harishankarr7/understanding-try-catch-throw-vs-no-throw-2i45

What happens if I don’t add a try-catch?
Let's explore this with an example:
🔧 Setup: Three methods calling each other

void Main() {
    A();
}

void A() {
    B();
}

void B() {
    C();
}

void C() {
    throw new Exception("Something broke in C!");
}

Enter fullscreen mode Exit fullscreen mode

🫧 What happens when you run Main()?
Main() calls A()

A() calls B()

B() calls C()

C() throws an exception ❌

But C doesn't catch it. So it bubbles up to:

B → no catch here → keep bubbling

A → still no catch → keep bubbling

Main → still no catch → boom 💥

You’ll get an unhandled exception.

🧠 That’s what bubbling means:
If a method doesn’t catch an exception, it passes it up to the method that called it.
That method can either catch it or keep passing it up the chain.

Like bubbles rising in water — they go up until something pops them (a catch block) — or they hit the surface (top of your app) and cause a splash (crash or 500 error).

So can I just sprinkle Try-Catch wherever I want?
What's the cost?

  1. Memory & CPU overhead
  • Even if nothing goes wrong, try-catch adds work
  • The runtime tracks the call stack and exception context
  • On some platforms (like .NET), this creates hidden metadata, and may even slow down JIT optimizations

💡 It’s like saying:

“Hey runtime, just in case I mess up, hold onto this backup plan.”
And that costs something, every time the method runs.

  1. **Exception throwing is super expensive
  • If an exception is actually thrown:
  • The runtime must unwind the call stack (walk backwards through function calls)
  • It creates a full exception object, often with stack trace, source info, etc.
  • This involves heap allocation, which is slow and can mess with garbage collection

⚠️ If you use exceptions to handle things like "this list is empty" or "this file is missing" — you're paying a high price for something you could’ve handled cheaply with an if.

🧠 So… when should you use try-catch?
✅ Good reasons:

  • You’re calling risky external code (like a file, database, API, or user input)
  • You want to add context to the error before rethrowing
  • You can actually recover from the error (like retry, fallback, or return a friendly error)

❌ Bad reasons:

  • “Just in case” — catching without knowing what might go wrong
  • You’re using it instead of if/else (e.g., catching FileNotFoundException instead of checking File.Exists)
  • You silently ignore the error (log-and-forget, or worse — do nothing)

✅ What to ask yourself before adding a try-catch:
Here’s your mental checklist:

-Can this code actually throw something?
If not — why are you catching?

-Is the exception expected or rare?
Expected → handle with if
Rare → handle with try-catch

-Can I fix or recover here?
If yes, catch and fix
If not, let it bubble up

-Will this block run thousands of times per second?
If yes, don’t put try-catch inside the loop — handle it outside

-Am I logging or hiding the exception?
If you’re not doing something useful, don’t catch it

💡 Mnemonic to remember:
✋ Only catch what you can coach
(If you can’t guide it or fix it, let it go.)

Top comments (0)