mirror of
https://github.com/dart-lang/sdk
synced 2024-09-16 03:17:55 +00:00
62f4712523
A new test captures a stack overflow error and rethrows it. It assumed that it would be a Dart `Error`, but on dartdevk it's not. Now just catches whatever it is and checks that it's the same object again. Bug: http://dartbug.com/47664 Change-Id: I2355ab1b43adf82806b0b76fc26aa5879ddb0d87 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/219788 Auto-Submit: Lasse R.H. Nielsen <lrn@google.com> Commit-Queue: Sigmund Cherem <sigmund@google.com> Reviewed-by: Sigmund Cherem <sigmund@google.com>
212 lines
6.5 KiB
Dart
212 lines
6.5 KiB
Dart
// Copyright (c) 2021, 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.
|
|
|
|
// @dart = 2.9
|
|
|
|
import "dart:async";
|
|
import "package:expect/expect.dart";
|
|
import "package:async_helper/async_helper.dart";
|
|
|
|
// Test of Error.throwWithStackTrace.
|
|
main() {
|
|
// Ensure `systemStack` is different from any other stack tracek.
|
|
var systemStack = (() => StackTrace.current)();
|
|
|
|
// Test that an error can be thrown with a system stack trace..
|
|
{
|
|
var error = ArgumentError("e1");
|
|
try {
|
|
Error.throwWithStackTrace(error, systemStack);
|
|
Expect.fail("Didn't throw: e1.1");
|
|
} on Error catch (e, s) {
|
|
Expect.identical(error, e, "e1.2");
|
|
// No not expect *identical* stack trace objects.
|
|
Expect.equals("$systemStack", "$s", "e1.3");
|
|
Expect.isNotNull(error.stackTrace, "e1.4");
|
|
Expect.equals("$systemStack", "${error.stackTrace}", "e1.5");
|
|
}
|
|
}
|
|
|
|
// Test that an error can be thrown with a user-created stack trace..
|
|
{
|
|
var stringStack = StackTrace.fromString("Nonce");
|
|
var error = ArgumentError("e2");
|
|
try {
|
|
Error.throwWithStackTrace(error, stringStack);
|
|
Expect.fail("Didn't throw: e2.1");
|
|
} on Error catch (e, s) {
|
|
Expect.identical(error, e, "e2.2");
|
|
// No not expect *identical* stack trace objects.
|
|
Expect.equals("$stringStack", "$s", "e2.3");
|
|
Expect.isNotNull(error.stackTrace, "e2.4");
|
|
Expect.equals("$stringStack", "${error.stackTrace}", "e2.5");
|
|
}
|
|
}
|
|
|
|
// Test that a non-error object can be thrown too.
|
|
{
|
|
var exception = FormatException("e3");
|
|
try {
|
|
Error.throwWithStackTrace(exception, systemStack);
|
|
Expect.fail("Didn't throw: e3.1");
|
|
} on Exception catch (e, s) {
|
|
Expect.identical(exception, e, "e3.2");
|
|
// No not expect *identical* stack trace objects.
|
|
Expect.equals("$systemStack", "$s", "e3.3");
|
|
}
|
|
}
|
|
|
|
// Test that an [Error] not extending {Error} can be thrown,
|
|
// but doesn't (and cannot) set the stack trace.
|
|
{
|
|
var error = CustomError("e4");
|
|
try {
|
|
Error.throwWithStackTrace(error, systemStack);
|
|
Expect.fail("Didn't throw: e4.1");
|
|
} on Error catch (e, s) {
|
|
Expect.identical(error, e, "e4.2");
|
|
// No not expect *identical* stack trace objects.
|
|
Expect.equals("$systemStack", "$s", "e4.3");
|
|
Expect.isNull(error.stackTrace, "e4.4");
|
|
}
|
|
}
|
|
|
|
// Test that an already set stack trace isn't changed.
|
|
{
|
|
var error = ArgumentError("e5");
|
|
StackTrace originalStack;
|
|
try {
|
|
throw error;
|
|
} on Error catch (e) {
|
|
originalStack = e.stackTrace;
|
|
}
|
|
Expect.isNotNull(originalStack);
|
|
Expect.notIdentical(originalStack, systemStack);
|
|
Expect.notEquals("$originalStack", "");
|
|
try {
|
|
Error.throwWithStackTrace(error, systemStack);
|
|
Expect.fail("Didn't throw: e5.1");
|
|
} on Error catch (e, s) {
|
|
Expect.identical(error, e, "e5.2");
|
|
// No not expect *identical* stack trace objects.
|
|
Expect.equals("$systemStack", "$s", "e5.3");
|
|
// Expect the already-set stack trace to stay.
|
|
Expect.isNotNull(error.stackTrace, "e5.4");
|
|
Expect.equals("$originalStack", "${error.stackTrace}", "e5.5");
|
|
}
|
|
}
|
|
|
|
// Works with OutOfMemoryError.
|
|
{
|
|
var error = const OutOfMemoryError();
|
|
try {
|
|
Error.throwWithStackTrace(error, systemStack);
|
|
} on Error catch (e, s) {
|
|
Expect.identical(error, e);
|
|
Expect.equals("$systemStack", "$s");
|
|
}
|
|
}
|
|
|
|
// Works with StackOverflowError.
|
|
{
|
|
var error = const StackOverflowError();
|
|
try {
|
|
Error.throwWithStackTrace(error, systemStack);
|
|
} on Error catch (e, s) {
|
|
Expect.identical(error, e);
|
|
Expect.equals("$systemStack", "$s");
|
|
}
|
|
}
|
|
|
|
// Also for live, captured, StackOverflowError.
|
|
{
|
|
Object error;
|
|
int foo() => foo() + 1;
|
|
try {
|
|
foo(); // Force stack overflow.
|
|
} catch (e, s) {
|
|
error = e;
|
|
}
|
|
// Some platforms might use another error than StackOverflowError.
|
|
// Should work with whichever object gets here.
|
|
try {
|
|
Error.throwWithStackTrace(error, systemStack);
|
|
} catch (e, s) {
|
|
Expect.identical(error, e);
|
|
Expect.equals("$systemStack", "$s");
|
|
}
|
|
}
|
|
|
|
asyncTest(() async {
|
|
var theFuture = Future.value(null);
|
|
|
|
// Test that throwing inside an asynchronous context can be caught.
|
|
{
|
|
var error = ArgumentError("e6");
|
|
try {
|
|
await theFuture;
|
|
Error.throwWithStackTrace(error, systemStack);
|
|
Expect.fail("Didn't throw: e6.1");
|
|
await theFuture;
|
|
} on Error catch (e, s) {
|
|
Expect.identical(error, e, "e6.2");
|
|
// No not expect *identical* stack trace objects.
|
|
Expect.equals("$systemStack", "$s", "e6.3");
|
|
Expect.isNotNull(error.stackTrace, "e6.4");
|
|
Expect.equals("$systemStack", "${error.stackTrace}", "e6.5");
|
|
}
|
|
}
|
|
|
|
// Test that throwing in asynchronous context can be locally uncaught.
|
|
{
|
|
asyncStart();
|
|
var error = ArgumentError("e7");
|
|
var future = () async {
|
|
await theFuture;
|
|
Error.throwWithStackTrace(error, systemStack);
|
|
Expect.fail("Didn't throw: e7.1");
|
|
await theFuture;
|
|
return null; // Force future type to Future<dynamic>
|
|
}();
|
|
future.catchError((e, s) {
|
|
Expect.identical(error, e, "e7.2");
|
|
// No not expect *identical* stack trace objects.
|
|
Expect.equals("$systemStack", "$s", "e7.3");
|
|
Expect.isNotNull(error.stackTrace, "e7.4");
|
|
Expect.equals("$systemStack", "${error.stackTrace}", "e7.5");
|
|
asyncEnd();
|
|
});
|
|
}
|
|
|
|
// Test throwing an uncaught async error caught by the Zone.
|
|
{
|
|
asyncStart();
|
|
var error = ArgumentError("e8");
|
|
await runZonedGuarded(() {
|
|
// Make an uncaught asynchronous error.
|
|
(() async {
|
|
await theFuture;
|
|
Error.throwWithStackTrace(error, systemStack);
|
|
Expect.fail("Didn't throw: e8.1");
|
|
await theFuture;
|
|
}());
|
|
}, (e, s) {
|
|
Expect.identical(error, e, "e8.2");
|
|
// No not expect *identical* stack trace objects.
|
|
Expect.equals("$systemStack", "$s", "e8.3");
|
|
Expect.isNotNull(error.stackTrace, "e8.4");
|
|
Expect.equals("$systemStack", "${error.stackTrace}", "e8.5");
|
|
asyncEnd();
|
|
});
|
|
}
|
|
});
|
|
}
|
|
|
|
class CustomError implements Error {
|
|
final String message;
|
|
CustomError(this.message);
|
|
StackTrace get stackTrace => null;
|
|
String toString() => "CustomError: $message";
|
|
}
|