Conversation
files/en-us/web/javascript/reference/statements/try...catch/index.md
Outdated
Show resolved
Hide resolved
files/en-us/web/javascript/reference/statements/try...catch/index.md
Outdated
Show resolved
Hide resolved
files/en-us/web/javascript/reference/statements/try...catch/index.md
Outdated
Show resolved
Hide resolved
files/en-us/web/javascript/reference/statements/try...catch/index.md
Outdated
Show resolved
Hide resolved
files/en-us/web/javascript/reference/statements/try...catch/index.md
Outdated
Show resolved
Hide resolved
files/en-us/web/javascript/reference/statements/try...catch/index.md
Outdated
Show resolved
Hide resolved
Josh-Cena
left a comment
There was a problem hiding this comment.
Thanks, I like this. Just some suggestions to make things more explicit.
| - Immediately after the `try` block finishes execution normally (and no exceptions were thrown); | ||
| - Immediately after the `catch` block finishes execution normally; | ||
| - Immediately before the execution of a control-flow statement (`return`, `throw`, `break`, `continue`) in the `try` block or `catch` block that would exit the block. | ||
| - Immediately after the control flow exits the `try` block in a `try...finally` construct (e.g., after the last statement or a `throw` or `return` statement); |
There was a problem hiding this comment.
| - Immediately after the control flow exits the `try` block in a `try...finally` construct (e.g., after the last statement or a `throw` or `return` statement); | |
| - Immediately after the control flow exits the `try` block in a `try...finally` construct (e.g., after the last statement or a `throw`, `return`, `break`, or `continue` statement); |
| - Immediately before the execution of a control-flow statement (`return`, `throw`, `break`, `continue`) in the `try` block or `catch` block that would exit the block. | ||
| - Immediately after the control flow exits the `try` block in a `try...finally` construct (e.g., after the last statement or a `throw` or `return` statement); | ||
| - Immediately after the control flow exits the `catch` block in a `try...catch...finally` construct; | ||
| - Immediately after the control flow exits the `try` block in a `try...catch...finally` construct, unless it exits via a `throw` statement (in which case control flow enters the `catch` block first); |
There was a problem hiding this comment.
| - Immediately after the control flow exits the `try` block in a `try...catch...finally` construct, unless it exits via a `throw` statement (in which case control flow enters the `catch` block first); | |
| - Immediately after the control flow exits the `try` block in a `try...catch...finally` construct, unless it exits via a `throw` statement (in which case control flow enters the `catch` block first). |
| - Immediately after the control flow exits the `try` block in a `try...catch...finally` construct, unless it exits via a `throw` statement (in which case control flow enters the `catch` block first); | ||
|
|
||
| If an exception is thrown from the `try` block, even when there's no `catch` block to handle the exception, the `finally` block still executes, in which case the exception is still thrown immediately after the `finally` block finishes executing. | ||
| In most cases, if the `finally` block is entered after a control flow statement (`return`, `throw`, `break`, `continue`), the effect of this statement is deferred until after the last statement executed in the `finally` block. However, if the last statement executed in the `finally` block is itself a control flow statement, that statement will override the effect of the previous one (no deferral). |
There was a problem hiding this comment.
| In most cases, if the `finally` block is entered after a control flow statement (`return`, `throw`, `break`, `continue`), the effect of this statement is deferred until after the last statement executed in the `finally` block. However, if the last statement executed in the `finally` block is itself a control flow statement, that statement will override the effect of the previous one (no deferral). | |
| If the `finally` block is entered after a control flow statement (`return`, `throw`, `break`, `continue`), the effect of this statement is deferred until after the last statement executed in the `finally` block. For example, if an exception is thrown from the `try` block, even when there's no `catch` block to handle the exception, the `finally` block still executes, in which case the exception is still thrown immediately after the `finally` block finishes executing and no other control flow statements were encountered. | |
| However, if the last statement executed in the `finally` block is itself a control flow statement, that statement will override the effect of the previous one (no deferral). |
There was a problem hiding this comment.
Added the canonical example with a few changes
- removed "and no other control flow statements were encountered" as I find it difficult to understand this before the general rule has been described (case where the
finallyends with a control flow statement) - changed "in which case the exception is still thrown" to "and the exception is thrown"
| ``` | ||
|
|
||
| Control flow statements (`return`, `throw`, `break`, `continue`) in the `finally` block will "mask" any completion value of the `try` block or `catch` block. In this example, the `try` block tries to return 1, but before returning, the control flow is yielded to the `finally` block first, so the `finally` block's return value is returned instead. | ||
| In the same way, any `return` statement in the `try` block is deferred at the end of the `finally` block. |
There was a problem hiding this comment.
| In the same way, any `return` statement in the `try` block is deferred at the end of the `finally` block. | |
| In the same way, any `return` statement in the `try` block is deferred at the end of the `finally` block, although the return value expression is evaluated before entering the `finally` block. |
There was a problem hiding this comment.
Applied. Also used "the effect of any return statement" for consistent terminology
| } | ||
| ``` | ||
|
|
||
| It is generally a bad idea to use control flow statements (`return`, `throw`, `break`, `continue`) in the `finally` block, as it makes the code harder to read. Most of the time, the `finally` block should be reserved for cleanup code. |
There was a problem hiding this comment.
| It is generally a bad idea to use control flow statements (`return`, `throw`, `break`, `continue`) in the `finally` block, as it makes the code harder to read. Most of the time, the `finally` block should be reserved for cleanup code. | |
| It is generally a bad idea to use control flow statements (`return`, `throw`, `break`, `continue`) in the `finally` block, because they will "mask" the original control flow effect, which is rarely intended. Most of the time, the `finally` block should be reserved for cleanup code. |
There was a problem hiding this comment.
Applied.
- Kept "which is rarely intended"
- Changed "mask" to "override" for consistent terminology
- Used "the effect of any previously executed control flow statement" for consistent terminology
|
|
||
| The following examples illustrate this. | ||
|
|
||
| If control flow reaches two `return` statements (possibly in the `try` and `finally` blocks or in the `catch` and `finally` blocks), both statements are executed in the correct order (which matters in the case of side effects). Only the function's returned value will be the one associated with the last `return` statement executed (which is the one in the `finally` block). |
There was a problem hiding this comment.
| If control flow reaches two `return` statements (possibly in the `try` and `finally` blocks or in the `catch` and `finally` blocks), both statements are executed in the correct order (which matters in the case of side effects). Only the function's returned value will be the one associated with the last `return` statement executed (which is the one in the `finally` block). | |
| If control flow exits the `try` or `catch` block via a `return` statement, the return value is evaluated (`order.sort()` in the example below). However, the `return` _statement_'s execution is deferred until the `finally` block finishes executing. Because the `finally` block also executes a `return` statement, the latter statement causes the first `return` to never execute. |
There was a problem hiding this comment.
Applied
- Kept the idea of describing the example in more detail
- Introduced "the function is planned to return..." terminology
- some control flow statements are not affected by the `finally` block (e.g. a `continue` inside and not exiting the `try` block)
|
@Josh-Cena as far as I am concerned, the PR is ready for a 2nd review. I tried to keep the core ideas behind your suggestions while also maintaining wording consistency. |
Josh-Cena
left a comment
There was a problem hiding this comment.
Nice, thank you! Now that the examples are more significant and self-contained, I moved them into the "Examples" section, which makes the description look leaner.
Description
Re-write
The finally blocksection in thetry...catchstatement documentation file trying to clarify control flow statements execution order while also keeping original structure and examples.Motivation
The main point to clarify is the combination of the 3rd bullet points and the following sentence:
return,throw,break,continue) in thetryblock orcatchblock that would exit the block."tryblock, even when there's nocatchblock to handle the exception, thefinallyblock still executes, in which case the exception is still thrown immediately after thefinallyblock finishes executing."The first part says that the
finallyblock is entered before the execution of the control flow statement that would exit thetryorcatchblock. The second implies that thefinallyblock still executes after an exception is thrown (or the execution of athrowstatement).The proposed re-writing try to fix this inconsistency by adopting a point of view in which:
finallyblock is always entered after the control flow statement that would exit thetryorcatchblockfinallyblock unless thefinallyblock also ends with a control flow statement.Additional details
Related issues and pull requests
Fixes #43122