Subjects

All subjects Django Java Python React Spring Boot JavaScript PHP
Sign Up Free
Interview question

What happens if an exception is thrown inside a finally block? finally block के अंदर exception throw हो तो क्या होता है?

Answer

An exception thrown in finally SUPPRESSES any exception from the try or catch block - only the finally block's exception propagates, and the original is lost unless explicitly captured.

public void problematic() {
    try {
        throw new RuntimeException('Original exception from try');
    } finally {
        throw new RuntimeException('Exception from finally');  // this WINS
    }
}

public static void main(String[] args) {
    try {
        new Main().problematic();
    } catch (RuntimeException e) {
        System.out.println(e.getMessage());  // 'Exception from finally' - original is LOST
    }
}

// This is considered a BAD PRACTICE because it silently discards
// the original error information, making debugging harder

// SAFER pattern - avoid throwing new exceptions in finally;
// only use finally for cleanup that itself shouldn't fail
public void safer() {
    Connection conn = null;
    try {
        conn = openConnection();
        performWork(conn);
    } finally {
        if (conn != null) {
            try {
                conn.close();  // wrap risky cleanup in its own try-catch
            } catch (Exception closeException) {
                System.out.println('Failed to close, but not masking original error');
            }
        }
    }
}

// try-with-resources handles this better automatically via 'suppressed exceptions'
// - if both the try block AND close() throw, the close() exception is
// added to the ORIGINAL exception's getSuppressed() array, not lost
try (MyResource r = new MyResource()) {
    throw new RuntimeException('try block error');
}
// catch (RuntimeException e) { e.getSuppressed(); } would show close() errors too

finally में throw हुई exception try या catch की exception को suppress कर देती है - सिर्फ finally की exception propagate होती है, original explicitly capture न करने पर खो जाती है।

public void problematic() {
    try {
        throw new RuntimeException('try से original exception');
    } finally {
        throw new RuntimeException('finally से exception');  // यह जीतती है
    }
}

public static void main(String[] args) {
    try {
        new Main().problematic();
    } catch (RuntimeException e) {
        System.out.println(e.getMessage());  // 'finally से exception' - original खो गई
    }
}

// यह bad practice है क्योंकि original error information चुपचाप खो जाती है

// सुरक्षित pattern - finally में नई exceptions throw करने से बचें
public void safer() {
    Connection conn = null;
    try {
        conn = openConnection();
        performWork(conn);
    } finally {
        if (conn != null) {
            try {
                conn.close();
            } catch (Exception closeException) {
                System.out.println('Close fail हुआ, original error mask नहीं हुआ');
            }
        }
    }
}

// try-with-resources इसे बेहतर handle करता है 'suppressed exceptions' से
try (MyResource r = new MyResource()) {
    throw new RuntimeException('try block error');
}
// e.getSuppressed() से close() की errors भी दिखेंगी

Was this answer clear?