UNPKG

6.87 kBJavaScriptView Raw
1/**
2 * @license
3 * Copyright Google Inc. All Rights Reserved.
4 *
5 * Use of this source code is governed by an MIT-style license that can be
6 * found in the LICENSE file at https://angular.io/license
7 */
8import { wrappedError } from './facade/errors';
9import { ERROR_ORIGINAL_ERROR, getOriginalError } from './facade/errors';
10import { stringify } from './facade/lang';
11function findFirstClosedCycle(keys) {
12 var res = [];
13 for (var i = 0; i < keys.length; ++i) {
14 if (res.indexOf(keys[i]) > -1) {
15 res.push(keys[i]);
16 return res;
17 }
18 res.push(keys[i]);
19 }
20 return res;
21}
22function constructResolvingPath(keys) {
23 if (keys.length > 1) {
24 var reversed = findFirstClosedCycle(keys.slice().reverse());
25 var tokenStrs = reversed.map(function (k) { return stringify(k.token); });
26 return ' (' + tokenStrs.join(' -> ') + ')';
27 }
28 return '';
29}
30function injectionError(injector, key, constructResolvingMessage, originalError) {
31 var error = (originalError ? wrappedError('', originalError) : Error());
32 error.addKey = addKey;
33 error.keys = [key];
34 error.injectors = [injector];
35 error.constructResolvingMessage = constructResolvingMessage;
36 error.message = error.constructResolvingMessage();
37 error[ERROR_ORIGINAL_ERROR] = originalError;
38 return error;
39}
40function addKey(injector, key) {
41 this.injectors.push(injector);
42 this.keys.push(key);
43 this.message = this.constructResolvingMessage();
44}
45/**
46 * Thrown when trying to retrieve a dependency by key from {@link Injector}, but the
47 * {@link Injector} does not have a {@link Provider} for the given key.
48 *
49 * ### Example ([live demo](http://plnkr.co/edit/vq8D3FRB9aGbnWJqtEPE?p=preview))
50 *
51 * ```typescript
52 * class A {
53 * constructor(b:B) {}
54 * }
55 *
56 * expect(() => Injector.resolveAndCreate([A])).toThrowError();
57 * ```
58 */
59export function noProviderError(injector, key) {
60 return injectionError(injector, key, function () {
61 var first = stringify(this.keys[0].token);
62 return "No provider for " + first + "!" + constructResolvingPath(this.keys);
63 });
64}
65/**
66 * Thrown when dependencies form a cycle.
67 *
68 * ### Example ([live demo](http://plnkr.co/edit/wYQdNos0Tzql3ei1EV9j?p=info))
69 *
70 * ```typescript
71 * var injector = Injector.resolveAndCreate([
72 * {provide: "one", useFactory: (two) => "two", deps: [[new Inject("two")]]},
73 * {provide: "two", useFactory: (one) => "one", deps: [[new Inject("one")]]}
74 * ]);
75 *
76 * expect(() => injector.get("one")).toThrowError();
77 * ```
78 *
79 * Retrieving `A` or `B` throws a `CyclicDependencyError` as the graph above cannot be constructed.
80 */
81export function cyclicDependencyError(injector, key) {
82 return injectionError(injector, key, function () {
83 return "Cannot instantiate cyclic dependency!" + constructResolvingPath(this.keys);
84 });
85}
86/**
87 * Thrown when a constructing type returns with an Error.
88 *
89 * The `InstantiationError` class contains the original error plus the dependency graph which caused
90 * this object to be instantiated.
91 *
92 * ### Example ([live demo](http://plnkr.co/edit/7aWYdcqTQsP0eNqEdUAf?p=preview))
93 *
94 * ```typescript
95 * class A {
96 * constructor() {
97 * throw new Error('message');
98 * }
99 * }
100 *
101 * var injector = Injector.resolveAndCreate([A]);
102
103 * try {
104 * injector.get(A);
105 * } catch (e) {
106 * expect(e instanceof InstantiationError).toBe(true);
107 * expect(e.originalException.message).toEqual("message");
108 * expect(e.originalStack).toBeDefined();
109 * }
110 * ```
111 */
112export function instantiationError(injector, originalException, originalStack, key) {
113 return injectionError(injector, key, function () {
114 var first = stringify(this.keys[0].token);
115 return getOriginalError(this).message + ": Error during instantiation of " + first + "!" + constructResolvingPath(this.keys) + ".";
116 }, originalException);
117}
118/**
119 * Thrown when an object other then {@link Provider} (or `Type`) is passed to {@link Injector}
120 * creation.
121 *
122 * ### Example ([live demo](http://plnkr.co/edit/YatCFbPAMCL0JSSQ4mvH?p=preview))
123 *
124 * ```typescript
125 * expect(() => Injector.resolveAndCreate(["not a type"])).toThrowError();
126 * ```
127 */
128export function invalidProviderError(provider) {
129 return Error("Invalid provider - only instances of Provider and Type are allowed, got: " + provider);
130}
131/**
132 * Thrown when the class has no annotation information.
133 *
134 * Lack of annotation information prevents the {@link Injector} from determining which dependencies
135 * need to be injected into the constructor.
136 *
137 * ### Example ([live demo](http://plnkr.co/edit/rHnZtlNS7vJOPQ6pcVkm?p=preview))
138 *
139 * ```typescript
140 * class A {
141 * constructor(b) {}
142 * }
143 *
144 * expect(() => Injector.resolveAndCreate([A])).toThrowError();
145 * ```
146 *
147 * This error is also thrown when the class not marked with {@link Injectable} has parameter types.
148 *
149 * ```typescript
150 * class B {}
151 *
152 * class A {
153 * constructor(b:B) {} // no information about the parameter types of A is available at runtime.
154 * }
155 *
156 * expect(() => Injector.resolveAndCreate([A,B])).toThrowError();
157 * ```
158 * @stable
159 */
160export function noAnnotationError(typeOrFunc, params) {
161 var signature = [];
162 for (var i = 0, ii = params.length; i < ii; i++) {
163 var parameter = params[i];
164 if (!parameter || parameter.length === 0) {
165 signature.push('?');
166 }
167 else {
168 signature.push(parameter.map(stringify).join(' '));
169 }
170 }
171 return Error("Cannot resolve all parameters for '" +
172 stringify(typeOrFunc) +
173 "'(" +
174 signature.join(', ') +
175 '). ' +
176 "Make sure that all the parameters are decorated with Inject or have valid type annotations and that '" +
177 stringify(typeOrFunc) +
178 "' is decorated with Injectable.");
179}
180/**
181 * Thrown when getting an object by index.
182 *
183 * ### Example ([live demo](http://plnkr.co/edit/bRs0SX2OTQiJzqvjgl8P?p=preview))
184 *
185 * ```typescript
186 * class A {}
187 *
188 * var injector = Injector.resolveAndCreate([A]);
189 *
190 * expect(() => injector.getAt(100)).toThrowError();
191 * ```
192 * @stable
193 */
194export function outOfBoundsError(index) {
195 return Error("Index " + index + " is out-of-bounds.");
196}
197// TODO: add a working example after alpha38 is released
198/**
199 * Thrown when a multi provider and a regular provider are bound to the same token.
200 *
201 * ### Example
202 *
203 * ```typescript
204 * expect(() => Injector.resolveAndCreate([
205 * { provide: "Strings", useValue: "string1", multi: true},
206 * { provide: "Strings", useValue: "string2", multi: false}
207 * ])).toThrowError();
208 * ```
209 */
210export function mixingMultiProvidersWithRegularProvidersError(provider1, provider2) {
211 return Error("Cannot mix multi providers and regular providers, got: " + provider1 + " " + provider2);
212}
213//# sourceMappingURL=reflective_errors.js.map
\No newline at end of file