From 6de879e0f557725d53f5411e9560274a42366c3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=96mer=20Sinan=20A=C4=9Facan?= Date: Fri, 5 Apr 2024 14:23:00 +0000 Subject: [PATCH] [dart2wasm] Fix exception handling in async functions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes #55347. Change-Id: I9ced2a4c06e6cb9714dc47e3661f5582c70cdeb0 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/361063 Reviewed-by: Erik Ernst Reviewed-by: Jackson Gardner Commit-Queue: Ömer Ağacan --- pkg/dart2wasm/lib/async.dart | 7 ++- .../exception/try_multiple_catch_async.dart | 52 +++++++++++++++++++ 2 files changed, 57 insertions(+), 2 deletions(-) create mode 100644 tests/language/exception/try_multiple_catch_async.dart diff --git a/pkg/dart2wasm/lib/async.dart b/pkg/dart2wasm/lib/async.dart index debed3faf86..180758f1c7c 100644 --- a/pkg/dart2wasm/lib/async.dart +++ b/pkg/dart2wasm/lib/async.dart @@ -1123,8 +1123,11 @@ class AsyncCodeGenerator extends CodeGenerator { for (int catchIdx = 0; catchIdx < node.catches.length; catchIdx += 1) { final Catch catch_ = node.catches[catchIdx]; - final Catch? nextCatch = - node.catches.length < catchIdx ? node.catches[catchIdx + 1] : null; + + final nextCatchIdx = catchIdx + 1; + final Catch? nextCatch = nextCatchIdx < node.catches.length + ? node.catches[nextCatchIdx] + : null; _emitTargetLabel(innerTargets[catch_]!); diff --git a/tests/language/exception/try_multiple_catch_async.dart b/tests/language/exception/try_multiple_catch_async.dart new file mode 100644 index 00000000000..33cb4d7f48a --- /dev/null +++ b/tests/language/exception/try_multiple_catch_async.dart @@ -0,0 +1,52 @@ +// Copyright (c) 2024, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +// Tests try-catch in `async`, with multiple `catch`/`on` blocks, where the +// first type test in the `catch`/`on` blocks fail and the subsequent test +// passes. +// +// This is a regression test for issue #55347. + +import 'package:expect/expect.dart'; + +class MyException implements Exception { + MyException([this.message]); + + final String? message; + + @override + String toString() => 'MyException($message)'; +} + +class MyOtherException implements Exception { + MyOtherException([this.message]); + + final String? message; + + @override + String toString() => 'MyOtherException($message)'; +} + +Future asynchronouslyThrowException() async { + throw MyException('Throwing an error!'); +} + +Future test() async { + try { + await asynchronouslyThrowException(); + Expect.fail('Exception is not thrown'); + } on MyOtherException { + Expect.fail('Wrong exception caught'); + } on MyException { + return 'Success'; + } catch (error) { + Expect.fail('Wrong exception caught'); + } + Expect.fail('No exception caught'); + return null; +} + +void main() async { + Expect.equals(await test(), 'Success'); +}