11import { ListWrapper , List } from 'angular2/src/facade/collection' ;
22import { stringify , BaseException , isBlank } from 'angular2/src/facade/lang' ;
3+ import { Key } from './key' ;
4+ import { Injector } from './injector' ;
35
46function findFirstClosedCycle ( keys : List < any > ) : List < any > {
57 var res = [ ] ;
@@ -31,22 +33,27 @@ function constructResolvingPath(keys: List<any>): string {
3133export class AbstractBindingError extends BaseException {
3234 name : string ;
3335 message : string ;
34- keys : List < any > ;
36+ keys : List < Key > ;
37+ injectors : List < Injector > ;
3538 constructResolvingMessage : Function ;
36- // TODO(tbosch): Can't do key:Key as this results in a circular dependency!
37- constructor ( key , constructResolvingMessage : Function , originalException ?, originalStack ?) {
38- super ( null , originalException , originalStack ) ;
39+
40+ constructor ( injector : Injector , key : Key , constructResolvingMessage : Function , originalException ?,
41+ originalStack ?) {
42+ super ( "DI Exception" , originalException , originalStack , null ) ;
3943 this . keys = [ key ] ;
44+ this . injectors = [ injector ] ;
4045 this . constructResolvingMessage = constructResolvingMessage ;
4146 this . message = this . constructResolvingMessage ( this . keys ) ;
4247 }
4348
44- // TODO(tbosch): Can't do key:Key as this results in a circular dependency!
45- addKey ( key : any ) : void {
49+ addKey ( injector : Injector , key : Key ) : void {
50+ this . injectors . push ( injector ) ;
4651 this . keys . push ( key ) ;
4752 this . message = this . constructResolvingMessage ( this . keys ) ;
4853 }
4954
55+ get context ( ) { return this . injectors [ this . injectors . length - 1 ] . debugContext ( ) ; }
56+
5057 toString ( ) : string { return this . message ; }
5158}
5259
@@ -55,47 +62,14 @@ export class AbstractBindingError extends BaseException {
5562 * {@link Injector} does not have a {@link Binding} for {@link Key}.
5663 */
5764export class NoBindingError extends AbstractBindingError {
58- // TODO(tbosch): Can't do key:Key as this results in a circular dependency!
59- constructor ( key ) {
60- super ( key , function ( keys : List < any > ) {
65+ constructor ( injector : Injector , key : Key ) {
66+ super ( injector , key , function ( keys : List < any > ) {
6167 var first = stringify ( ListWrapper . first ( keys ) . token ) ;
6268 return `No provider for ${ first } !${ constructResolvingPath ( keys ) } ` ;
6369 } ) ;
6470 }
6571}
6672
67- /**
68- * Thrown when trying to retrieve an async {@link Binding} using the sync API.
69- *
70- * ## Example
71- *
72- * ```javascript
73- * var injector = Injector.resolveAndCreate([
74- * bind(Number).toAsyncFactory(() => {
75- * return new Promise((resolve) => resolve(1 + 2));
76- * }),
77- * bind(String).toFactory((v) => { return "Value: " + v; }, [String])
78- * ]);
79- *
80- * injector.asyncGet(String).then((v) => expect(v).toBe('Value: 3'));
81- * expect(() => {
82- * injector.get(String);
83- * }).toThrowError(AsycBindingError);
84- * ```
85- *
86- * The above example throws because `String` depends on `Number` which is async. If any binding in
87- * the dependency graph is async then the graph can only be retrieved using the `asyncGet` API.
88- */
89- export class AsyncBindingError extends AbstractBindingError {
90- // TODO(tbosch): Can't do key:Key as this results in a circular dependency!
91- constructor ( key ) {
92- super ( key , function ( keys : List < any > ) {
93- var first = stringify ( ListWrapper . first ( keys ) . token ) ;
94- return `Cannot instantiate ${ first } synchronously. It is provided as a promise!${ constructResolvingPath ( keys ) } ` ;
95- } ) ;
96- }
97- }
98-
9973/**
10074 * Thrown when dependencies form a cycle.
10175 *
@@ -113,9 +87,8 @@ export class AsyncBindingError extends AbstractBindingError {
11387 * Retrieving `A` or `B` throws a `CyclicDependencyError` as the graph above cannot be constructed.
11488 */
11589export class CyclicDependencyError extends AbstractBindingError {
116- // TODO(tbosch): Can't do key:Key as this results in a circular dependency!
117- constructor ( key ) {
118- super ( key , function ( keys : List < any > ) {
90+ constructor ( injector : Injector , key : Key ) {
91+ super ( injector , key , function ( keys : List < any > ) {
11992 return `Cannot instantiate cyclic dependency!${ constructResolvingPath ( keys ) } ` ;
12093 } ) ;
12194 }
@@ -128,14 +101,13 @@ export class CyclicDependencyError extends AbstractBindingError {
128101 * this object to be instantiated.
129102 */
130103export class InstantiationError extends AbstractBindingError {
131- causeKey ;
132-
133- // TODO(tbosch): Can't do key:Key as this results in a circular dependency!
134- constructor ( originalException , originalStack , key ) {
135- super ( key , function ( keys : List < any > ) {
104+ causeKey : Key ;
105+ constructor ( injector : Injector , originalException , originalStack , key : Key ) {
106+ super ( injector , key , function ( keys : List < any > ) {
136107 var first = stringify ( ListWrapper . first ( keys ) . token ) ;
137108 return `Error during instantiation of ${ first } !${ constructResolvingPath ( keys ) } .` +
138- ` ORIGINAL ERROR: ${ originalException } ` + `\n\n ORIGINAL STACK: ${ originalStack } ` ;
109+ `\n\n ORIGINAL ERROR: ${ originalException } ` +
110+ `\n\n ORIGINAL STACK: ${ originalStack } \n` ;
139111 } , originalException , originalStack ) ;
140112
141113 this . causeKey = key ;
0 commit comments