Skip to content

Commit

Permalink
Merge pull request #71 from LoveCommunity/fix/scope-dispose-if-config…
Browse files Browse the repository at this point in the history
…ure-throw

scope auto dispose if configuration throw error
  • Loading branch information
beeth0ven committed Jul 9, 2022
2 parents a407c78 + 2d1ff88 commit 84669f3
Show file tree
Hide file tree
Showing 2 changed files with 80 additions and 8 deletions.
28 changes: 20 additions & 8 deletions lib/src/scopes/shared/build_scope.dart
Original file line number Diff line number Diff line change
Expand Up @@ -14,21 +14,33 @@ FutureOr<Scope> buildScope(List<Configurable> configure, ConfigurableScope scope

@internal
FutureOr<void> configureScope(List<Configurable> configure, ConfigurableScope scope) {
return configure
.fold<FutureOr<void>>(null, (futureOrVoid, configurable) {
return futureOrVoid.then((_) => configurable.configure(scope));
});
try {
final result = configure
.fold<FutureOr<void>>(null, (futureOrVoid, configurable) {
return futureOrVoid.then((_) => configurable.configure(scope));
});
if (result is Future<void>) {
return result.catchError(
(error, stackTrace) {
scope.dispose();
return Future.error(error, stackTrace);
}
);
}
} catch(_) {
scope.dispose();
rethrow;
}
}

extension <T> on FutureOr<T> {

FutureOr<R> then<R>(
FutureOr<R> Function(T) onValue, {
FutureOr<R> Function(Object error, StackTrace stackTrace)? onError,
}) {
FutureOr<R> Function(T) onValue
) {
final _this = this;
if (_this is Future<T>) {
return _this.then(onValue, onError: onError);
return _this.then(onValue);
} else {
return onValue(_this);
}
Expand Down
60 changes: 60 additions & 0 deletions test/scopes/scope_methods/disposable_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,66 @@ void main() {

});

test('`scope` auto dispose if sync configuration throw error', () async {

int invokes = 0;
Object? error;

final configurable = MockConfigurable((scope) {

final disposable = Disposable(() {
invokes += 1;
});

scope.addDisposable(disposable);

throw 'error';

});

try {
await Scope.root([
configurable,
]);
} catch(e) {
error = e;
}

expect(invokes, 1);
expect(error, 'error');

});

test('`scope` auto dispose if async configuration throw error', () async {

int invokes = 0;
Object? error;

final configurable = MockConfigurable((scope) async {

final disposable = Disposable(() {
invokes += 1;
});

scope.addDisposable(disposable);

throw 'error';

});

try {
await Scope.root([
configurable,
]);
} catch(e) {
error = e;
}

expect(invokes, 1);
expect(error, 'error');

});

test('`scope.addDispose` register dispose logic', () async {

int invokes = 0;
Expand Down

0 comments on commit 84669f3

Please sign in to comment.