@@ -165,6 +165,7 @@ export const transformTryStatement: FunctionVisitor<ts.TryStatement> = (statemen
165165
166166 const tryResultIdentifier = lua . createIdentifier ( "____try" ) ;
167167 const returnValueIdentifier = lua . createIdentifier ( "____returnValue" ) ;
168+ const rethrowIdentifier = lua . createIdentifier ( "____rethrow" ) ;
168169
169170 const result : lua . Statement [ ] = [ ] ;
170171
@@ -191,6 +192,9 @@ export const transformTryStatement: FunctionVisitor<ts.TryStatement> = (statemen
191192 }
192193 }
193194 result . push ( lua . createVariableDeclarationStatement ( tryReturnIdentifiers , tryCall ) ) ;
195+ if ( statement . finallyBlock ) {
196+ result . push ( lua . createVariableDeclarationStatement ( rethrowIdentifier ) ) ;
197+ }
194198
195199 const catchCall = lua . createCallExpression (
196200 catchIdentifier ,
@@ -203,8 +207,22 @@ export const transformTryStatement: FunctionVisitor<ts.TryStatement> = (statemen
203207 )
204208 : lua . createExpressionStatement ( catchCall ) ;
205209
210+ const catchCallFunction = lua . createFunctionExpression ( lua . createBlock ( [ catchCallStatement ] ) ) ;
211+
212+ const tryCatchCall = lua . createCallExpression ( pCall , [ catchCallFunction ] ) ;
213+
214+ const tryCatchCallStatement = lua . createAssignmentStatement (
215+ [ lua . cloneIdentifier ( tryResultIdentifier ) , lua . cloneIdentifier ( rethrowIdentifier ) ] ,
216+ tryCatchCall
217+ ) ;
218+
206219 const notTryCondition = lua . createUnaryExpression ( tryResultIdentifier , lua . SyntaxKind . NotOperator ) ;
207- result . push ( lua . createIfStatement ( notTryCondition , lua . createBlock ( [ catchCallStatement ] ) ) ) ;
220+ result . push (
221+ lua . createIfStatement (
222+ notTryCondition ,
223+ lua . createBlock ( statement . finallyBlock ? [ tryCatchCallStatement ] : [ catchCallStatement ] )
224+ )
225+ ) ;
208226 } else if ( tryScope . functionReturned ) {
209227 // try with return, but no catch
210228 // returnedIdentifier = lua.createIdentifier("____returned");
@@ -230,21 +248,33 @@ export const transformTryStatement: FunctionVisitor<ts.TryStatement> = (statemen
230248 result . push ( ...context . transformStatements ( statement . finallyBlock ) ) ;
231249 }
232250
233- // Re-throw error if try had no catch but had a finally.
251+ // Re-throw error if try had a finally.
234252 // On pcall failure the error is the second return value, which lands in
235253 // ____hasReturned (when functionReturned) or ____error (otherwise).
236- if ( ! statement . catchClause && statement . finallyBlock ) {
254+ if ( statement . finallyBlock ) {
237255 const notTryCondition = lua . createUnaryExpression (
238256 lua . cloneIdentifier ( tryResultIdentifier ) ,
239257 lua . SyntaxKind . NotOperator
240258 ) ;
241- const errorIdentifier = tryScope . functionReturned
242- ? lua . cloneIdentifier ( returnedIdentifier )
243- : lua . createIdentifier ( "____error" ) ;
244- const rethrow = lua . createExpressionStatement (
245- lua . createCallExpression ( lua . createIdentifier ( "error" ) , [ errorIdentifier , lua . createNumericLiteral ( 0 ) ] )
246- ) ;
247- result . push ( lua . createIfStatement ( notTryCondition , lua . createBlock ( [ rethrow ] ) ) ) ;
259+
260+ if ( ! statement . catchClause ) {
261+ const errorIdentifier = tryScope . functionReturned
262+ ? lua . cloneIdentifier ( returnedIdentifier )
263+ : lua . createIdentifier ( "____error" ) ;
264+ const rethrow = lua . createExpressionStatement (
265+ lua . createCallExpression ( lua . createIdentifier ( "error" ) , [ errorIdentifier , lua . createNumericLiteral ( 0 ) ] )
266+ ) ;
267+ result . push ( lua . createIfStatement ( notTryCondition , lua . createBlock ( [ rethrow ] ) ) ) ;
268+ } else if ( statement . catchClause . block . statements . length > 0 ) {
269+ // Re-throw is possible only from non-empty blocks.
270+ const rethrow = lua . createExpressionStatement (
271+ lua . createCallExpression ( lua . createIdentifier ( "error" ) , [
272+ rethrowIdentifier ,
273+ lua . createNumericLiteral ( 0 ) ,
274+ ] )
275+ ) ;
276+ result . push ( lua . createIfStatement ( notTryCondition , lua . createBlock ( [ rethrow ] ) ) ) ;
277+ }
248278 }
249279
250280 if ( returnCondition && returnedIdentifier ) {
0 commit comments