mirror of
https://github.com/dart-lang/sdk
synced 2024-09-18 21:01:20 +00:00
Revert "Fail synchronously if null is passed as an error to async APIs."
This reverts commit bef363bfb7
.
Reason for revert: Breaks google3 tests, see b/151204525.
Original change's description:
> Fail synchronously if null is passed as an error to async APIs.
>
> The first patchset is Lasse's original changes.
>
> Change-Id: Ic5f24bcfc0ef4e82edee68d61e015b095cb5916e
> Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/138605
> Reviewed-by: Leaf Petersen <leafp@google.com>
TBR=leafp@google.com,rnystrom@google.com
Change-Id: Ie17c35e9d23c70a7aecd1ef292962154cf6f007d
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/138925
Reviewed-by: David Morgan <davidmorgan@google.com>
Commit-Queue: David Morgan <davidmorgan@google.com>
This commit is contained in:
parent
e6a1e70960
commit
a5bf30c401
|
@ -115,7 +115,6 @@ class _WebSocketProtocolTransformer extends StreamTransformerBase<List<int>,
|
|||
}
|
||||
|
||||
void addError(Object error, [StackTrace stackTrace]) {
|
||||
ArgumentError.checkNotNull(error, "error");
|
||||
_eventSink.addError(error, stackTrace);
|
||||
}
|
||||
|
||||
|
@ -724,7 +723,6 @@ class _WebSocketOutgoingTransformer
|
|||
}
|
||||
|
||||
void addError(Object error, [StackTrace stackTrace]) {
|
||||
ArgumentError.checkNotNull(error, "error");
|
||||
_eventSink.addError(error, stackTrace);
|
||||
}
|
||||
|
||||
|
|
|
@ -419,7 +419,6 @@ class _AsyncStarImpl<T> {
|
|||
}
|
||||
|
||||
void addError(Object error, StackTrace stackTrace) {
|
||||
ArgumentError.checkNotNull(error, "error");
|
||||
if (cancellationCompleter != null && !cancellationCompleter.isCompleted) {
|
||||
// If the stream has been cancelled, complete the cancellation future
|
||||
// with the error.
|
||||
|
|
|
@ -209,7 +209,6 @@ class _AsyncStarStreamController<T> {
|
|||
}
|
||||
|
||||
void addError(Object error, StackTrace stackTrace) {
|
||||
ArgumentError.checkNotNull(error, "error");
|
||||
if ((cancellationFuture != null) && cancellationFuture._mayComplete) {
|
||||
// If the stream has been cancelled, complete the cancellation future
|
||||
// with the error.
|
||||
|
|
|
@ -253,7 +253,7 @@ abstract class _BroadcastStreamController<T>
|
|||
}
|
||||
|
||||
void addError(Object error, [StackTrace stackTrace]) {
|
||||
ArgumentError.checkNotNull(error, "error");
|
||||
error = _nonNullError(error);
|
||||
if (!_mayAddEvent) throw _addEventError();
|
||||
AsyncError replacement = Zone.current.errorCallback(error, stackTrace);
|
||||
if (replacement != null) {
|
||||
|
@ -480,7 +480,6 @@ class _AsBroadcastStreamController<T> extends _SyncBroadcastStreamController<T>
|
|||
}
|
||||
|
||||
void addError(Object error, [StackTrace stackTrace]) {
|
||||
ArgumentError.checkNotNull(error, "error");
|
||||
if (!isClosed && _isFiring) {
|
||||
_addPendingEvent(new _DelayedError(error, stackTrace));
|
||||
return;
|
||||
|
|
|
@ -266,12 +266,12 @@ abstract class Future<T> {
|
|||
* If an error handler isn't added before the future completes, the error
|
||||
* will be considered unhandled.
|
||||
*
|
||||
* The [error] must not be `null`.
|
||||
* If [error] is `null`, it is replaced by a [NullThrownError].
|
||||
*
|
||||
* Use [Completer] to create a future and complete it later.
|
||||
*/
|
||||
factory Future.error(Object error, [StackTrace stackTrace]) {
|
||||
ArgumentError.checkNotNull(error, "error");
|
||||
error = _nonNullError(error);
|
||||
if (!identical(Zone.current, _rootZone)) {
|
||||
AsyncError replacement = Zone.current.errorCallback(error, stackTrace);
|
||||
if (replacement != null) {
|
||||
|
@ -874,7 +874,7 @@ abstract class Completer<T> {
|
|||
* Completing a future with an error indicates that an exception was thrown
|
||||
* while trying to produce a value.
|
||||
*
|
||||
* The [error] must not be `null`.
|
||||
* If [error] is `null`, it is replaced by a [NullThrownError].
|
||||
*
|
||||
* If `error` is a `Future`, the future itself is used as the error value.
|
||||
* If you want to complete with the result of the future, you can use:
|
||||
|
|
|
@ -19,7 +19,7 @@ abstract class _Completer<T> implements Completer<T> {
|
|||
void complete([FutureOr<T> value]);
|
||||
|
||||
void completeError(Object error, [StackTrace stackTrace]) {
|
||||
ArgumentError.checkNotNull(error, "error");
|
||||
error = _nonNullError(error);
|
||||
if (!future._mayComplete) throw new StateError("Future already completed");
|
||||
AsyncError replacement = Zone.current.errorCallback(error, stackTrace);
|
||||
if (replacement != null) {
|
||||
|
@ -94,8 +94,8 @@ class _FutureListener<S, T> {
|
|||
this.result, _FutureOnValue<S, T> onValue, Function errorCallback)
|
||||
: callback = onValue,
|
||||
errorCallback = errorCallback,
|
||||
state = ((errorCallback == null) ? stateThen : stateThenOnerror) |
|
||||
stateIsAwait;
|
||||
state = ((errorCallback == null) ? stateThen : stateThenOnerror)
|
||||
| stateIsAwait ;
|
||||
|
||||
_FutureListener.catchError(this.result, this.errorCallback, this.callback)
|
||||
: state = (callback == null) ? stateCatcherror : stateCatcherrorTest;
|
||||
|
@ -293,7 +293,8 @@ class _Future<T> implements Future<T> {
|
|||
/// The system created liseners are not registered in the zone,
|
||||
/// and the listener is marked as being from an `await`.
|
||||
/// This marker is used in [_continuationFunctions].
|
||||
Future<E> _thenAwait<E>(FutureOr<E> f(T value), Function onError) {
|
||||
Future<E> _thenAwait<E>(
|
||||
FutureOr<E> f(T value), Function onError) {
|
||||
_Future<E> result = new _Future<E>();
|
||||
_addListener(new _FutureListener<T, E>.thenAwait(result, f, onError));
|
||||
return result;
|
||||
|
@ -811,5 +812,5 @@ Function _registerErrorHandler(Function errorHandler, Zone zone) {
|
|||
errorHandler,
|
||||
"onError",
|
||||
"Error handler must accept one Object or one Object and a StackTrace"
|
||||
" as arguments, and return a a valid result");
|
||||
" as arguments, and return a a valid result");
|
||||
}
|
||||
|
|
|
@ -132,7 +132,6 @@ abstract class Stream<T> {
|
|||
*
|
||||
* This stream emits a single error event of [error] and [stackTrace]
|
||||
* and then completes with a done event.
|
||||
* The [error] must not be `null`.
|
||||
*
|
||||
* Example:
|
||||
* ```dart
|
||||
|
@ -153,13 +152,11 @@ abstract class Stream<T> {
|
|||
* stack trace as well.
|
||||
*/
|
||||
@Since("2.5")
|
||||
factory Stream.error(Object error, [StackTrace stackTrace]) {
|
||||
ArgumentError.checkNotNull(error, "error");
|
||||
return (_AsyncStreamController<T>(null, null, null, null)
|
||||
.._addError(error, stackTrace)
|
||||
.._closeUnchecked())
|
||||
.stream;
|
||||
}
|
||||
factory Stream.error(Object error, [StackTrace stackTrace]) =>
|
||||
(_AsyncStreamController<T>(null, null, null, null)
|
||||
.._addError(error, stackTrace)
|
||||
.._closeUnchecked())
|
||||
.stream;
|
||||
|
||||
/**
|
||||
* Creates a new single-subscription stream from the future.
|
||||
|
@ -1814,8 +1811,6 @@ abstract class EventSink<T> implements Sink<T> {
|
|||
/**
|
||||
* Adds an [error] to the sink.
|
||||
*
|
||||
* The [error] must not be `null`.
|
||||
*
|
||||
* Must not be called on a closed sink.
|
||||
*/
|
||||
void addError(Object error, [StackTrace stackTrace]);
|
||||
|
|
|
@ -237,7 +237,7 @@ abstract class StreamController<T> implements StreamSink<T> {
|
|||
/**
|
||||
* Sends or enqueues an error event.
|
||||
*
|
||||
* The [error] must not be `null`.
|
||||
* If [error] is `null`, it is replaced by a [NullThrownError].
|
||||
*
|
||||
* Listeners receive this event at a later microtask. This behavior can be
|
||||
* overridden by using `sync` controllers. Note, however, that sync
|
||||
|
@ -361,8 +361,6 @@ abstract class SynchronousStreamController<T> implements StreamController<T> {
|
|||
/**
|
||||
* Adds error to the controller's stream.
|
||||
*
|
||||
* The [error] must not be `null`.
|
||||
*
|
||||
* As [StreamController.addError], but must not be called while an event is
|
||||
* being added by [add], [addError] or [close].
|
||||
*/
|
||||
|
@ -599,11 +597,8 @@ abstract class _StreamController<T> implements _StreamControllerBase<T> {
|
|||
|
||||
/**
|
||||
* Send or enqueue an error event.
|
||||
*
|
||||
* The [error] must not be `null`.
|
||||
*/
|
||||
void addError(Object error, [StackTrace stackTrace]) {
|
||||
ArgumentError.checkNotNull(error, "error");
|
||||
if (!_mayAddEvent) throw _badEventState();
|
||||
error = _nonNullError(error);
|
||||
AsyncError replacement = Zone.current.errorCallback(error, stackTrace);
|
||||
|
|
|
@ -234,7 +234,6 @@ class _HandlerEventSink<S, T> implements EventSink<S> {
|
|||
}
|
||||
|
||||
void addError(Object error, [StackTrace stackTrace]) {
|
||||
ArgumentError.checkNotNull(error, "error");
|
||||
if (_isClosed) {
|
||||
throw StateError("Sink is closed");
|
||||
}
|
||||
|
|
|
@ -43,9 +43,7 @@ class AsyncError implements Error {
|
|||
final Object error;
|
||||
final StackTrace stackTrace;
|
||||
|
||||
AsyncError(this.error, this.stackTrace) {
|
||||
ArgumentError.checkNotNull(error, "error");
|
||||
}
|
||||
AsyncError(this.error, this.stackTrace);
|
||||
|
||||
String toString() => '$error';
|
||||
}
|
||||
|
@ -752,7 +750,6 @@ class _ZoneDelegate implements ZoneDelegate {
|
|||
}
|
||||
|
||||
AsyncError errorCallback(Zone zone, Object error, StackTrace stackTrace) {
|
||||
ArgumentError.checkNotNull(error, "error");
|
||||
var implementation = _delegationTarget._errorCallback;
|
||||
_Zone implZone = implementation.zone;
|
||||
if (identical(implZone, _rootZone)) return null;
|
||||
|
@ -1068,7 +1065,6 @@ class _CustomZone extends _Zone {
|
|||
}
|
||||
|
||||
AsyncError errorCallback(Object error, StackTrace stackTrace) {
|
||||
ArgumentError.checkNotNull(error, "error");
|
||||
var implementation = this._errorCallback;
|
||||
assert(implementation != null);
|
||||
final Zone implementationZone = implementation.zone;
|
||||
|
@ -1113,11 +1109,8 @@ class _CustomZone extends _Zone {
|
|||
|
||||
void _rootHandleUncaughtError(
|
||||
Zone self, ZoneDelegate parent, Zone zone, error, StackTrace stackTrace) {
|
||||
if (error == null) {
|
||||
error = ArgumentError.notNull("error");
|
||||
stackTrace = StackTrace.current;
|
||||
}
|
||||
_schedulePriorityAsyncCallback(() {
|
||||
error ??= new NullThrownError();
|
||||
if (stackTrace == null) throw error;
|
||||
_rethrow(error, stackTrace);
|
||||
});
|
||||
|
|
|
@ -75,7 +75,6 @@ class _ConverterStreamEventSink<S, T> implements EventSink<S> {
|
|||
}
|
||||
|
||||
void addError(Object error, [StackTrace stackTrace]) {
|
||||
ArgumentError.checkNotNull(error, "error");
|
||||
_eventSink.addError(error, stackTrace);
|
||||
}
|
||||
|
||||
|
|
|
@ -113,8 +113,6 @@ class _WebSocketProtocolTransformer extends StreamTransformerBase<List<int>,
|
|||
}
|
||||
|
||||
void addError(Object error, [StackTrace? stackTrace]) {
|
||||
// TODO(40614): Remove once non-nullability is sound.
|
||||
ArgumentError.checkNotNull(error, "error");
|
||||
_eventSink!.addError(error, stackTrace);
|
||||
}
|
||||
|
||||
|
@ -724,8 +722,6 @@ class _WebSocketOutgoingTransformer
|
|||
}
|
||||
|
||||
void addError(Object error, [StackTrace? stackTrace]) {
|
||||
// TODO(40614): Remove once non-nullability is sound.
|
||||
ArgumentError.checkNotNull(error, "error");
|
||||
_eventSink!.addError(error, stackTrace);
|
||||
}
|
||||
|
||||
|
@ -1220,7 +1216,6 @@ class _WebSocketImpl extends Stream with _ServiceObject implements WebSocket {
|
|||
}
|
||||
|
||||
void addUtf8Text(List<int> bytes) {
|
||||
// TODO(40614): Remove once non-nullability is sound.
|
||||
ArgumentError.checkNotNull(bytes, "bytes");
|
||||
_sink.add(new _EncodedString(bytes));
|
||||
}
|
||||
|
|
|
@ -417,7 +417,6 @@ class _AsyncStarImpl<T> {
|
|||
}
|
||||
|
||||
void addError(Object error, StackTrace stackTrace) {
|
||||
ArgumentError.checkNotNull(error, "error");
|
||||
var completer = cancellationCompleter;
|
||||
if (completer != null && !completer.isCompleted) {
|
||||
// If the stream has been cancelled, complete the cancellation future
|
||||
|
|
|
@ -214,8 +214,6 @@ class _AsyncStarStreamController<T> {
|
|||
}
|
||||
|
||||
void addError(Object error, StackTrace stackTrace) {
|
||||
// TODO(40614): Remove once non-nullability is sound.
|
||||
ArgumentError.checkNotNull(error, "error");
|
||||
final future = cancellationFuture;
|
||||
if ((future != null) && future._mayComplete) {
|
||||
// If the stream has been cancelled, complete the cancellation future
|
||||
|
|
|
@ -248,8 +248,6 @@ abstract class _BroadcastStreamController<T>
|
|||
}
|
||||
|
||||
void addError(Object error, [StackTrace? stackTrace]) {
|
||||
// TODO(40614): Remove once non-nullability is sound.
|
||||
ArgumentError.checkNotNull(error, "error");
|
||||
if (!_mayAddEvent) throw _addEventError();
|
||||
AsyncError? replacement = Zone.current.errorCallback(error, stackTrace);
|
||||
if (replacement != null) {
|
||||
|
@ -478,8 +476,6 @@ class _AsBroadcastStreamController<T> extends _SyncBroadcastStreamController<T>
|
|||
}
|
||||
|
||||
void addError(Object error, [StackTrace? stackTrace]) {
|
||||
// TODO(40614): Remove once non-nullability is sound.
|
||||
ArgumentError.checkNotNull(error, "error");
|
||||
if (!isClosed && _isFiring) {
|
||||
_addPendingEvent(new _DelayedError(error, stackTrace));
|
||||
return;
|
||||
|
|
|
@ -269,11 +269,11 @@ abstract class Future<T> {
|
|||
* If an error handler isn't added before the future completes, the error
|
||||
* will be considered unhandled.
|
||||
*
|
||||
* If [error] is `null`, it is replaced by a [NullThrownError].
|
||||
*
|
||||
* Use [Completer] to create a future and complete it later.
|
||||
*/
|
||||
factory Future.error(Object error, [StackTrace? stackTrace]) {
|
||||
// TODO(40614): Remove once non-nullability is sound.
|
||||
ArgumentError.checkNotNull(error, "error");
|
||||
if (!identical(Zone.current, _rootZone)) {
|
||||
AsyncError? replacement = Zone.current.errorCallback(error, stackTrace);
|
||||
if (replacement != null) {
|
||||
|
|
|
@ -17,8 +17,6 @@ abstract class _Completer<T> implements Completer<T> {
|
|||
void complete([FutureOr<T>? value]);
|
||||
|
||||
void completeError(Object error, [StackTrace? stackTrace]) {
|
||||
// TODO(40614): Remove once non-nullability is sound.
|
||||
ArgumentError.checkNotNull(error, "error");
|
||||
if (!future._mayComplete) throw new StateError("Future already completed");
|
||||
AsyncError? replacement = Zone.current.errorCallback(error, stackTrace);
|
||||
if (replacement != null) {
|
||||
|
|
|
@ -150,14 +150,11 @@ abstract class Stream<T> {
|
|||
* stack trace as well.
|
||||
*/
|
||||
@Since("2.5")
|
||||
factory Stream.error(Object error, [StackTrace? stackTrace]) {
|
||||
// TODO(40614): Remove once non-nullability is sound.
|
||||
ArgumentError.checkNotNull(error, "error");
|
||||
return (_AsyncStreamController<T>(null, null, null, null)
|
||||
.._addError(error, stackTrace)
|
||||
.._closeUnchecked())
|
||||
.stream;
|
||||
}
|
||||
factory Stream.error(Object error, [StackTrace? stackTrace]) =>
|
||||
(_AsyncStreamController<T>(null, null, null, null)
|
||||
.._addError(error, stackTrace)
|
||||
.._closeUnchecked())
|
||||
.stream;
|
||||
|
||||
/**
|
||||
* Creates a new single-subscription stream from the future.
|
||||
|
|
|
@ -600,8 +600,6 @@ abstract class _StreamController<T> implements _StreamControllerBase<T> {
|
|||
* Send or enqueue an error event.
|
||||
*/
|
||||
void addError(Object error, [StackTrace? stackTrace]) {
|
||||
// TODO(40614): Remove once non-nullability is sound.
|
||||
ArgumentError.checkNotNull(error, "error");
|
||||
if (!_mayAddEvent) throw _badEventState();
|
||||
AsyncError? replacement = Zone.current.errorCallback(error, stackTrace);
|
||||
if (replacement != null) {
|
||||
|
|
|
@ -229,8 +229,6 @@ class _HandlerEventSink<S, T> implements EventSink<S> {
|
|||
}
|
||||
|
||||
void addError(Object error, [StackTrace? stackTrace]) {
|
||||
// TODO(40614): Remove once non-nullability is sound.
|
||||
ArgumentError.checkNotNull(error, "error");
|
||||
var sink = _sink;
|
||||
if (sink == null) {
|
||||
throw StateError("Sink is closed");
|
||||
|
|
|
@ -41,10 +41,7 @@ class AsyncError implements Error {
|
|||
final Object error;
|
||||
final StackTrace? stackTrace;
|
||||
|
||||
AsyncError(this.error, this.stackTrace) {
|
||||
// TODO(40614): Remove once non-nullability is sound.
|
||||
ArgumentError.checkNotNull(error, "error");
|
||||
}
|
||||
AsyncError(this.error, this.stackTrace);
|
||||
|
||||
String toString() => '$error';
|
||||
}
|
||||
|
@ -745,8 +742,6 @@ class _ZoneDelegate implements ZoneDelegate {
|
|||
}
|
||||
|
||||
AsyncError? errorCallback(Zone zone, Object error, StackTrace? stackTrace) {
|
||||
// TODO(40614): Remove once non-nullability is sound.
|
||||
ArgumentError.checkNotNull(error, "error");
|
||||
var implementation = _delegationTarget._errorCallback;
|
||||
_Zone implZone = implementation.zone;
|
||||
if (identical(implZone, _rootZone)) return null;
|
||||
|
@ -1080,8 +1075,6 @@ class _CustomZone extends _Zone {
|
|||
}
|
||||
|
||||
AsyncError? errorCallback(Object error, StackTrace? stackTrace) {
|
||||
// TODO(40614): Remove once non-nullability is sound.
|
||||
ArgumentError.checkNotNull(error, "error");
|
||||
var implementation = this._errorCallback;
|
||||
final _Zone implementationZone = implementation.zone;
|
||||
if (identical(implementationZone, _rootZone)) return null;
|
||||
|
|
|
@ -73,8 +73,6 @@ class _ConverterStreamEventSink<S, T> implements EventSink<S> {
|
|||
}
|
||||
|
||||
void addError(Object error, [StackTrace? stackTrace]) {
|
||||
// TODO(40614): Remove once non-nullability is sound.
|
||||
ArgumentError.checkNotNull(error, "error");
|
||||
_eventSink.addError(error, stackTrace);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,13 +0,0 @@
|
|||
// Copyright (c) 2020, 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.
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:expect/expect.dart';
|
||||
|
||||
main() {
|
||||
// The error cannot be null.
|
||||
Expect.throwsArgumentError(() {
|
||||
Future.error(null);
|
||||
});
|
||||
}
|
|
@ -697,10 +697,13 @@ void testCompleteErrorWithCustomFuture() {
|
|||
}
|
||||
|
||||
void testCompleteErrorWithNull() {
|
||||
asyncStart();
|
||||
final completer = new Completer<int>();
|
||||
Expect.throwsArgumentError(() {
|
||||
completer.completeError(null);
|
||||
completer.future.catchError((e) {
|
||||
Expect.isTrue(e is NullThrownError);
|
||||
asyncEnd();
|
||||
});
|
||||
completer.completeError(null);
|
||||
}
|
||||
|
||||
void testChainedFutureValue() {
|
||||
|
|
|
@ -1,48 +0,0 @@
|
|||
// Copyright (c) 2020, 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.
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:expect/expect.dart';
|
||||
|
||||
main() {
|
||||
// Single-cast async.
|
||||
var controller = StreamController();
|
||||
Expect.throwsArgumentError(() {
|
||||
controller.addError(null);
|
||||
});
|
||||
|
||||
Expect.throwsArgumentError(() {
|
||||
controller.sink.addError(null);
|
||||
});
|
||||
|
||||
// Single-cast sync.
|
||||
controller = StreamController(sync: true);
|
||||
Expect.throwsArgumentError(() {
|
||||
controller.addError(null);
|
||||
});
|
||||
|
||||
Expect.throwsArgumentError(() {
|
||||
controller.sink.addError(null);
|
||||
});
|
||||
|
||||
// Broadcast async.
|
||||
controller = StreamController.broadcast();
|
||||
Expect.throwsArgumentError(() {
|
||||
controller.addError(null);
|
||||
});
|
||||
|
||||
Expect.throwsArgumentError(() {
|
||||
controller.sink.addError(null);
|
||||
});
|
||||
|
||||
// Broadcast sync.
|
||||
controller = StreamController.broadcast(sync: true);
|
||||
Expect.throwsArgumentError(() {
|
||||
controller.addError(null);
|
||||
});
|
||||
|
||||
Expect.throwsArgumentError(() {
|
||||
controller.sink.addError(null);
|
||||
});
|
||||
}
|
|
@ -72,11 +72,6 @@ void main() async {
|
|||
await onDone.future;
|
||||
}
|
||||
|
||||
// A null error argument is a synchronous error.
|
||||
Expect.throwsArgumentError(() {
|
||||
Stream.error(null);
|
||||
});
|
||||
|
||||
asyncEnd();
|
||||
}
|
||||
|
||||
|
|
|
@ -1,13 +0,0 @@
|
|||
// Copyright (c) 2020, 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.
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:expect/expect.dart';
|
||||
|
||||
main() {
|
||||
// The error cannot be null.
|
||||
Expect.throwsArgumentError(() {
|
||||
AsyncError(null, StackTrace.current);
|
||||
});
|
||||
}
|
Loading…
Reference in a new issue