feat(core): add source to StaticInjectorError message (#20817)

Closes #19302
PR Close #20817
This commit is contained in:
Olivier Combe
2017-12-06 10:13:50 +01:00
committed by Jason Aden
parent 634d33f5dd
commit b7738e1fe5
11 changed files with 106 additions and 34 deletions

View File

@ -8,12 +8,12 @@
import {Type} from '../type';
import {stringify} from '../util';
import {resolveForwardRef} from './forward_ref';
import {InjectionToken} from './injection_token';
import {Inject, Optional, Self, SkipSelf} from './metadata';
import {ConstructorProvider, ExistingProvider, FactoryProvider, StaticClassProvider, StaticProvider, ValueProvider} from './provider';
export const SOURCE = '__source';
const _THROW_IF_NOT_FOUND = new Object();
export const THROW_IF_NOT_FOUND = _THROW_IF_NOT_FOUND;
@ -64,6 +64,13 @@ export abstract class Injector {
*/
abstract get(token: any, notFoundValue?: any): any;
/**
* @deprecated from v5 use the new signature Injector.create(options)
*/
static create(providers: StaticProvider[], parent?: Injector): Injector;
static create(options: {providers: StaticProvider[], parent?: Injector, name?: string}): Injector;
/**
* Create a new Injector which is configure using `StaticProvider`s.
*
@ -71,8 +78,14 @@ export abstract class Injector {
*
* {@example core/di/ts/provider_spec.ts region='ConstructorProvider'}
*/
static create(providers: StaticProvider[], parent?: Injector): Injector {
return new StaticInjector(providers, parent);
static create(
options: StaticProvider[]|{providers: StaticProvider[], parent?: Injector, name?: string},
parent?: Injector): Injector {
if (Array.isArray(options)) {
return new StaticInjector(options, parent);
} else {
return new StaticInjector(options.providers, options.parent, options.name || null);
}
}
}
@ -103,11 +116,14 @@ const NO_NEW_LINE = 'ɵ';
export class StaticInjector implements Injector {
readonly parent: Injector;
readonly source: string|null;
private _records: Map<any, Record>;
constructor(providers: StaticProvider[], parent: Injector = NULL_INJECTOR) {
constructor(
providers: StaticProvider[], parent: Injector = NULL_INJECTOR, source: string|null = null) {
this.parent = parent;
this.source = source;
const records = this._records = new Map<any, Record>();
records.set(
Injector, <Record>{token: Injector, fn: IDENT, deps: EMPTY, value: this, useNew: false});
@ -122,7 +138,10 @@ export class StaticInjector implements Injector {
return tryResolveToken(token, record, this._records, this.parent, notFoundValue);
} catch (e) {
const tokenPath: any[] = e[NG_TEMP_TOKEN_PATH];
e.message = formatError('\n' + e.message, tokenPath);
if (token[SOURCE]) {
tokenPath.unshift(token[SOURCE]);
}
e.message = formatError('\n' + e.message, tokenPath, this.source);
e[NG_TOKEN_PATH] = tokenPath;
e[NG_TEMP_TOKEN_PATH] = null;
throw e;
@ -336,7 +355,7 @@ function computeDeps(provider: StaticProvider): DependencyRecord[] {
return deps;
}
function formatError(text: string, obj: any): string {
function formatError(text: string, obj: any, source: string | null = null): string {
text = text && text.charAt(0) === '\n' && text.charAt(1) == NO_NEW_LINE ? text.substr(2) : text;
let context = stringify(obj);
if (obj instanceof Array) {
@ -352,7 +371,7 @@ function formatError(text: string, obj: any): string {
}
context = `{${parts.join(', ')}}`;
}
return `StaticInjectorError[${context}]: ${text.replace(NEW_LINE, '\n ')}`;
return `StaticInjectorError${source ? '(' + source + ')' : ''}[${context}]: ${text.replace(NEW_LINE, '\n ')}`;
}
function staticError(text: string, obj: any): Error {