🚨
Exception Handling

try, catch, throw

Errors Ko Gracefully Handle Karo
💡 Exception handling ek safety net jaisa hai circus mein — agar acrobat (code) girta hai (error aata hai), net (catch block) usse pakad leta hai, poora show (program) crash nahi hota.

C mein error handling manual hai (return codes check karte raho, jaise malloc() ka NULL check). C++ "exceptions" deta hai — ek structured tareeka errors ko signal karne aur handle karne ka, normal code flow se alag.

try block mein wo code likhte ho jo fail ho sakta hai. Agar exception throw hoti hai (throw keyword se), control seedha matching catch block mein jump karta hai — beech ka baaki code skip ho jaata hai. Agar koi exception nahi aati, catch block simply skip ho jaata hai.

#include <stdexcept>
using namespace std;

double divide(double a, double b) {
  if (b == 0) {
    throw runtime_error("Division by zero!");  // exception throw karo
  }
  return a / b;
}

int main() {
  try {
    cout << divide(10, 2) << endl;   // 5 — normal
    cout << divide(5, 0) << endl;    // exception throw hoga
    cout << "Ye line kabhi nahi chalegi" << endl;
  } catch (const runtime_error &e) {
    cout << "Error: " << e.what() << endl;   // "Error: Division by zero!"
  }

  cout << "Program continue chal raha hai" << endl;  // crash nahi hua
  return 0;
}
🚨
Exception handling ek safety net jaisa hai circus mein — agar acrobat (code) girta hai (error aata hai), net (catch block) usse pakad leta hai, poora show (program) crash nahi hota.
1 / 6
⚡ Quick Recap
  • throw = exception signal karo, try = risky code, catch = handle karo
  • Exception aane par control seedha catch block mein jump karta hai
  • Unhandled exception poora program crash kar deta hai
On this page (2 subtopics)

Ek try block ke saath multiple catch blocks ho sakte hain — alag-alag exception types ke liye alag handling. Order matter karta hai: specific types pehle, generic (jaise catch(...)) sabse aakhir mein.

try {
  // risky code
  throw runtime_error("something failed");
} catch (const invalid_argument &e) {
  cout << "Invalid argument: " << e.what() << endl;
} catch (const runtime_error &e) {
  cout << "Runtime error: " << e.what() << endl;  // ye chalega
} catch (...) {
  cout << "Kuch aur exception aayi" << endl;  // catch-all, sabse last
}
💡Tip: catch (...) "catch everything" hai — koi bhi type ka exception pakad leta hai, lekin exception ki details (message) nahi mil paati. Usually last resort ke roop mein use hota hai.

Jab exception throw hoti hai aur try block se bahar propagate hoti hai (catch tak pahunchne ke liye), beech mein aane wale saare local objects ke destructors automatically call hote hain ("stack unwinding") — RAII pattern isi guarantee par depend karta hai resource cleanup ke liye.

class Resource {
  public:
    ~Resource() { cout << "Resource cleaned up!" << endl; }
};

void risky() {
  Resource r;   // local object
  throw runtime_error("Oops");
  // r ka destructor yahin nahi chalega (unreachable code hai)
}

int main() {
  try {
    risky();
  } catch (...) {
    cout << "Caught" << endl;
  }
  // Output: "Resource cleaned up!" (stack unwind hote waqt) phir "Caught"
  return 0;
}
💡Tip: Ye RAII (Resource Acquisition Is Initialization) ka poora point hai — chahe exception aaye ya na aaye, destructors guaranteed chalte hain, isliye smart pointers/file handles automatically cleanup ho jaate hain.