From 62004e22e023669952762cc6776d7a3b81a5fea4 Mon Sep 17 00:00:00 2001 From: vsavkin Date: Tue, 7 Oct 2014 09:04:11 -0400 Subject: [PATCH] feat(injector): change injector to show the full path when error happens in a constructor (async) --- modules/di/src/injector.js | 19 +++++++++++++++---- modules/di/test/di/async_spec.js | 13 +++++++++++++ modules/facade/src/async.dart | 8 ++++++++ modules/facade/src/async.es6 | 8 ++++++++ 4 files changed, 44 insertions(+), 4 deletions(-) diff --git a/modules/di/src/injector.js b/modules/di/src/injector.js index f8529560a6..560f6b93c6 100644 --- a/modules/di/src/injector.js +++ b/modules/di/src/injector.js @@ -186,7 +186,9 @@ class _AsyncInjectorStrategy { this.injector._setInstance(key, _constructing); var deps = this._resolveDependencies(key, binding); - var future = FutureWrapper.wait(deps). + var depsFuture = FutureWrapper.wait(deps); + + var future = FutureWrapper.catchError(depsFuture, (e) => this._errorHandler(key, e)). then(deps => this._findOrCreate(key, binding, deps)). then(instance => this._cacheInstance(key, instance)); @@ -205,10 +207,19 @@ class _AsyncInjectorStrategy { } } + _errorHandler(key:Key, e):Future { + if (e instanceof ProviderError) e.addKey(key); + return FutureWrapper.error(e); + } + _findOrCreate(key:Key, binding: Binding, deps:List) { - var instance = this.injector._getInstance(key); - if (! _isWaiting(instance)) return instance; - return binding.factory(deps); + try { + var instance = this.injector._getInstance(key); + if (!_isWaiting(instance)) return instance; + return binding.factory(deps); + } catch (e) { + throw new InstantiationError(e, key); + } } _cacheInstance(key, instance) { diff --git a/modules/di/test/di/async_spec.js b/modules/di/test/di/async_spec.js index 0265656983..cb7444ba88 100644 --- a/modules/di/test/di/async_spec.js +++ b/modules/di/test/di/async_spec.js @@ -100,6 +100,19 @@ export function main () { done(); }); }); + + it('should show the full path when error happens in a constructor', function(done) { + var injector = new Injector([ + UserController, + bind(UserList).toAsyncFactory([], function(){throw "Broken UserList";}) + ]); + + var future = injector.asyncGet(UserController); + FutureWrapper.catchError(future, function (e) { + expect(e.message).toContain("Error during instantiation of UserList! (UserController -> UserList)"); + done(); + }); + }); }); describe("get", function () { diff --git a/modules/facade/src/async.dart b/modules/facade/src/async.dart index 6ea2f23049..f2bc8096aa 100644 --- a/modules/facade/src/async.dart +++ b/modules/facade/src/async.dart @@ -8,7 +8,15 @@ class FutureWrapper { return new Future.value(obj); } + static Future error(obj) { + return new Future.error(obj); + } + static Future wait(List futures){ return Future.wait(futures); } + + static Future catchError(Future future, Function onError){ + return future.catchError(onError); + } } diff --git a/modules/facade/src/async.es6 b/modules/facade/src/async.es6 index 7bf7568bca..0d05b1b1bf 100644 --- a/modules/facade/src/async.es6 +++ b/modules/facade/src/async.es6 @@ -5,8 +5,16 @@ export class FutureWrapper { return Future.resolve(obj); } + static error(obj):Future { + return Future.reject(obj); + } + static wait(futures):Future { if (futures.length == 0) return Future.resolve([]); return Future.all(futures); } + + static catchError(future:Future, onError:Function):Future { + return future.catch(onError); + } } \ No newline at end of file