Examples
Nested try-blocks
First, let's see what happens with this:
try { try { throw new Error('oops'); } finally { console.log('finally'); } } catch (ex) { console.error('outer', ex.message); } // Output: // "finally" // "outer" "oops"
Now, if we already caught the exception in the inner try
-block by adding a
catch
-block:
try { try { throw new Error('oops'); } catch (ex) { console.error('inner', ex.message); } finally { console.log('finally'); } } catch (ex) { console.error('outer', ex.message); } // Output: // "inner" "oops" // "finally"
And now, let's rethrow the error.
try { try { throw new Error('oops'); } catch (ex) { console.error('inner', ex.message); throw ex; } finally { console.log('finally'); } } catch (ex) { console.error('outer', ex.message); } // Output: // "inner" "oops" // "finally" // "outer" "oops"
Any given exception will be caught only once by the nearest enclosing
catch
-block unless it is rethrown. Of course, any new exceptions raised in
the "inner" block (because the code in catch
-block may do something that
throws), will be caught by the "outer" block.
Returning from a finally-block
If the finally
-block returns a value, this value becomes the return value
of the entire try-catch-finally
statement, regardless of any
return
statements in the try
and catch
-blocks.
This includes exceptions thrown inside of the catch
-block:
() => { try { try { throw new Error('oops'); } catch (ex) { console.error('inner', ex.message); throw ex; } finally { console.log('finally'); return; } } catch (ex) { console.error('outer', ex.message); } })(); // Output: // "inner" "oops" // "finally"
The outer "oops" is not thrown because of the return in the finally
-block.
The same would apply to any value returned from the catch
-block.