The documentation states that if a procedure called in a TRY-CATCH has a TRY-CATCH, control is passed back after the CATCH block finishes. Here is the text,
"TRY…CATCH constructs catch unhandled errors from stored procedures or triggers executed by the code in the TRY block. Alternatively, the stored procedures or triggers can contain their own TRY…CATCH constructs to handle errors generated by their code. For example, when a TRY block executes a stored procedure and an error occurs in the stored procedure, the error can be handled in the following ways:
If the stored procedure does not contain its own TRY…CATCH construct, the error returns control to the CATCH block associated with the TRY block that contains the EXECUTE statement.
If the stored procedure contains a TRY…CATCH construct, the error transfers control to the CATCH block in the stored procedure. When the CATCH block code finishes, control is passed back to the statement immediately after the EXECUTE statement that called the stored procedure."
I find that control is not passed back to the caller until the end of the procedure. Perhaps the documentation assumes that the END CATCH is the last statement in the procedure called?
In addition, if there is an error in the CATCH block that is not handled, the flow will pass immediately to the CATCH of the calling procedure.
If the procedure is not nested, an unhandled error in the CATCH block does not pass control to the caller. In this case, the flow continues in the CATCH block and to the code following the CATCH block.
The documentation should clarify this - especially if I have it wrong.