Failure to construct ErrorWidget for build errors does not destroy tree (#117090)

diff --git a/packages/flutter/lib/src/widgets/framework.dart b/packages/flutter/lib/src/widgets/framework.dart
index 217828f..6aa7ba3 100644
--- a/packages/flutter/lib/src/widgets/framework.dart
+++ b/packages/flutter/lib/src/widgets/framework.dart
@@ -4711,12 +4711,15 @@
       owner!._debugCurrentBuildTarget = this;
       return true;
     }());
-    performRebuild();
-    assert(() {
-      assert(owner!._debugCurrentBuildTarget == this);
-      owner!._debugCurrentBuildTarget = debugPreviousBuildTarget;
-      return true;
-    }());
+    try {
+      performRebuild();
+    } finally {
+      assert(() {
+        assert(owner!._debugCurrentBuildTarget == this);
+        owner!._debugCurrentBuildTarget = debugPreviousBuildTarget;
+        return true;
+      }());
+    }
     assert(!_dirty);
   }
 
diff --git a/packages/flutter/test/widgets/error_widget_test.dart b/packages/flutter/test/widgets/error_widget_test.dart
new file mode 100644
index 0000000..b91bfdc
--- /dev/null
+++ b/packages/flutter/test/widgets/error_widget_test.dart
@@ -0,0 +1,92 @@
+// Copyright 2014 The Flutter Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+import 'package:flutter/foundation.dart';
+import 'package:flutter/material.dart';
+import 'package:flutter_test/flutter_test.dart';
+
+void main() {
+  testWidgets('ErrorWidget displays actual error when throwing during build', (WidgetTester tester) async {
+    final Key container = UniqueKey();
+    const String errorText = 'Oh no, there was a crash!!1';
+
+    await tester.pumpWidget(
+      Container(
+        key: container,
+        color: Colors.red,
+        padding: const EdgeInsets.all(10),
+        child: Builder(
+          builder: (BuildContext context) {
+            throw UnsupportedError(errorText);
+          },
+        ),
+      ),
+    );
+
+    expect(
+      tester.takeException(),
+      isA<UnsupportedError>().having((UnsupportedError error) => error.message, 'message', contains(errorText)),
+    );
+
+    final ErrorWidget errorWidget = tester.widget(find.byType(ErrorWidget));
+    expect(errorWidget.message, contains(errorText));
+
+    // Failure in one widget shouldn't ripple through the entire tree and effect
+    // ancestors. Those should still be in the tree.
+    expect(find.byKey(container), findsOneWidget);
+  });
+
+  testWidgets('when constructing an ErrorWidget due to a build failure throws an error, fail gracefully', (WidgetTester tester) async {
+    final Key container = UniqueKey();
+    await tester.pumpWidget(
+      Container(
+        key: container,
+        color: Colors.red,
+        padding: const EdgeInsets.all(10),
+        // This widget throws during build, which causes the construction of an
+        // ErrorWidget with the build error. However, during construction of
+        // that ErrorWidget, another error is thrown.
+        child: const MyDoubleThrowingWidget(),
+      ),
+    );
+
+    expect(
+      tester.takeException(),
+      isA<UnsupportedError>().having((UnsupportedError error) => error.message, 'message', contains(MyThrowingElement.debugFillPropertiesErrorMessage)),
+    );
+
+    final ErrorWidget errorWidget = tester.widget(find.byType(ErrorWidget));
+    expect(errorWidget.message, contains(MyThrowingElement.debugFillPropertiesErrorMessage));
+
+    // Failure in one widget shouldn't ripple through the entire tree and effect
+    // ancestors. Those should still be in the tree.
+    expect(find.byKey(container), findsOneWidget);
+  });
+}
+
+// This widget throws during its regular build and then again when the
+// ErrorWidget is constructed, which calls MyThrowingElement.debugFillProperties.
+class MyDoubleThrowingWidget extends StatelessWidget {
+  const MyDoubleThrowingWidget({super.key});
+
+  @override
+  StatelessElement createElement() => MyThrowingElement(this);
+
+  @override
+  Widget build(BuildContext context) {
+    throw UnsupportedError('You cannot build me!');
+  }
+}
+
+class MyThrowingElement extends StatelessElement {
+  MyThrowingElement(super.widget);
+
+  static const String debugFillPropertiesErrorMessage = 'Crash during debugFillProperties';
+
+  @override
+  void debugFillProperties(DiagnosticPropertiesBuilder properties) {
+    super.debugFillProperties(properties);
+    throw UnsupportedError(debugFillPropertiesErrorMessage);
+  }
+}