refactor(compiler): don't print stack trace on template parse errors (#13390)

This commit is contained in:
Bowen Ni
2016-12-15 13:07:12 -08:00
committed by Chuck Jazdzewski
parent 14e785f5b7
commit f0e092515c
13 changed files with 102 additions and 71 deletions

View File

@ -88,7 +88,7 @@ export class StaticSymbolResolver {
}
} else {
let value = baseMetadata;
for (var i = 0; i < members.length && value; i++) {
for (let i = 0; i < members.length && value; i++) {
value = value[members[i]];
}
return new ResolvedStaticSymbol(staticSymbol, value);

View File

@ -127,7 +127,7 @@ export enum CompileSummaryKind {
* the directive / module itself.
*/
export interface CompileTypeSummary {
summaryKind: CompileSummaryKind
summaryKind: CompileSummaryKind;
type: CompileTypeMetadata;
}

View File

@ -19,7 +19,7 @@ import {ResourceLoader} from './resource_loader';
import {extractStyleUrls, isStyleUrlResolvable} from './style_url_resolver';
import {PreparsedElementType, preparseElement} from './template_parser/template_preparser';
import {UrlResolver} from './url_resolver';
import {SyncAsyncResult} from './util';
import {SyncAsyncResult, SyntaxError} from './util';
export interface PrenormalizedTemplateMetadata {
componentType: any;
@ -71,7 +71,7 @@ export class DirectiveNormalizer {
} else if (prenormData.templateUrl) {
normalizedTemplateAsync = this.normalizeTemplateAsync(prenormData);
} else {
throw new Error(
throw new SyntaxError(
`No template specified for component ${stringify(prenormData.componentType)}`);
}
@ -105,7 +105,7 @@ export class DirectiveNormalizer {
template, stringify(prenomData.componentType), false, interpolationConfig);
if (rootNodesAndErrors.errors.length > 0) {
const errorString = rootNodesAndErrors.errors.join('\n');
throw new Error(`Template parse errors:\n${errorString}`);
throw new SyntaxError(`Template parse errors:\n${errorString}`);
}
const templateMetadataStyles = this.normalizeStylesheet(new CompileStylesheetMetadata({
styles: prenomData.styles,

View File

@ -24,7 +24,7 @@ import {ComponentStillLoadingError, LIFECYCLE_HOOKS_VALUES, ReflectorReader, ref
import {ElementSchemaRegistry} from './schema/element_schema_registry';
import {SummaryResolver} from './summary_resolver';
import {getUrlScheme} from './url_resolver';
import {MODULE_SUFFIX, SyncAsyncResult, ValueTransformer, visitValue} from './util';
import {MODULE_SUFFIX, SyncAsyncResult, SyntaxError, ValueTransformer, visitValue} from './util';
export type ErrorCollector = (error: any, type?: any) => void;
export const ERROR_COLLECTOR_TOKEN = new OpaqueToken('ErrorCollector');
@ -253,7 +253,7 @@ export class CompileMetadataResolver {
// Directive
if (!selector) {
this._reportError(
new Error(`Directive ${stringifyType(directiveType)} has no selector, please add it!`),
new SyntaxError(`Directive ${stringifyType(directiveType)} has no selector, please add it!`),
directiveType);
selector = 'error';
}
@ -299,7 +299,7 @@ export class CompileMetadataResolver {
const dirMeta = this._directiveCache.get(directiveType);
if (!dirMeta) {
this._reportError(
new Error(
new SyntaxError(
`Illegal state: getDirectiveMetadata can only be called after loadNgModuleMetadata for a module that declares it. Directive ${stringifyType(directiveType)}.`),
directiveType);
}
@ -311,7 +311,7 @@ export class CompileMetadataResolver {
<cpl.CompileDirectiveSummary>this._loadSummary(dirType, cpl.CompileSummaryKind.Directive);
if (!dirSummary) {
this._reportError(
new Error(
new SyntaxError(
`Illegal state: Could not load the summary for directive ${stringifyType(dirType)}.`),
dirType);
}
@ -394,7 +394,7 @@ export class CompileMetadataResolver {
const importedModuleSummary = this.getNgModuleSummary(importedModuleType);
if (!importedModuleSummary) {
this._reportError(
new Error(
new SyntaxError(
`Unexpected ${this._getTypeDescriptor(importedType)} '${stringifyType(importedType)}' imported by the module '${stringifyType(moduleType)}'`),
moduleType);
return;
@ -402,7 +402,7 @@ export class CompileMetadataResolver {
importedModules.push(importedModuleSummary);
} else {
this._reportError(
new Error(
new SyntaxError(
`Unexpected value '${stringifyType(importedType)}' imported by the module '${stringifyType(moduleType)}'`),
moduleType);
return;
@ -414,7 +414,7 @@ export class CompileMetadataResolver {
flattenAndDedupeArray(meta.exports).forEach((exportedType) => {
if (!isValidType(exportedType)) {
this._reportError(
new Error(
new SyntaxError(
`Unexpected value '${stringifyType(exportedType)}' exported by the module '${stringifyType(moduleType)}'`),
moduleType);
return;
@ -435,7 +435,7 @@ export class CompileMetadataResolver {
flattenAndDedupeArray(meta.declarations).forEach((declaredType) => {
if (!isValidType(declaredType)) {
this._reportError(
new Error(
new SyntaxError(
`Unexpected value '${stringifyType(declaredType)}' declared by the module '${stringifyType(moduleType)}'`),
moduleType);
return;
@ -452,7 +452,7 @@ export class CompileMetadataResolver {
this._addTypeToModule(declaredType, moduleType);
} else {
this._reportError(
new Error(
new SyntaxError(
`Unexpected ${this._getTypeDescriptor(declaredType)} '${stringifyType(declaredType)}' declared by the module '${stringifyType(moduleType)}'`),
moduleType);
return;
@ -471,7 +471,7 @@ export class CompileMetadataResolver {
transitiveModule.addExportedPipe(exportedId);
} else {
this._reportError(
new Error(
new SyntaxError(
`Can't export ${this._getTypeDescriptor(exportedId.reference)} ${stringifyType(exportedId.reference)} from ${stringifyType(moduleType)} as it was neither declared nor imported!`),
moduleType);
}
@ -494,7 +494,7 @@ export class CompileMetadataResolver {
flattenAndDedupeArray(meta.bootstrap).forEach(type => {
if (!isValidType(type)) {
this._reportError(
new Error(
new SyntaxError(
`Unexpected value '${stringifyType(type)}' used in the bootstrap property of module '${stringifyType(moduleType)}'`),
moduleType);
return;
@ -557,7 +557,7 @@ export class CompileMetadataResolver {
const oldModule = this._ngModuleOfTypes.get(type);
if (oldModule && oldModule !== moduleType) {
this._reportError(
new Error(
new SyntaxError(
`Type ${stringifyType(type)} is part of the declarations of 2 modules: ${stringifyType(oldModule)} and ${stringifyType(moduleType)}! ` +
`Please consider moving ${stringifyType(type)} to a higher module that imports ${stringifyType(oldModule)} and ${stringifyType(moduleType)}. ` +
`You can also create a new NgModule that exports and includes ${stringifyType(type)} then import that NgModule in ${stringifyType(oldModule)} and ${stringifyType(moduleType)}.`),
@ -653,7 +653,7 @@ export class CompileMetadataResolver {
const pipeMeta = this._pipeCache.get(pipeType);
if (!pipeMeta) {
this._reportError(
new Error(
new SyntaxError(
`Illegal state: getPipeMetadata can only be called after loadNgModuleMetadata for a module that declares it. Pipe ${stringifyType(pipeType)}.`),
pipeType);
}
@ -665,7 +665,7 @@ export class CompileMetadataResolver {
<cpl.CompilePipeSummary>this._loadSummary(pipeType, cpl.CompileSummaryKind.Pipe);
if (!pipeSummary) {
this._reportError(
new Error(
new SyntaxError(
`Illegal state: Could not load the summary for pipe ${stringifyType(pipeType)}.`),
pipeType);
}
@ -748,7 +748,7 @@ export class CompileMetadataResolver {
const depsTokens =
dependenciesMetadata.map((dep) => dep ? stringifyType(dep.token) : '?').join(', ');
this._reportError(
new Error(
new SyntaxError(
`Can't resolve all parameters for ${stringifyType(typeOrFunc)}: (${depsTokens}).`),
typeOrFunc);
}
@ -797,7 +797,7 @@ export class CompileMetadataResolver {
[]))
.join(', ');
this._reportError(
new Error(
new SyntaxError(
`Invalid ${debugInfo ? debugInfo : 'provider'} - only instances of Provider and Type are allowed, got: [${providersInfo}]`),
type);
}
@ -818,13 +818,14 @@ export class CompileMetadataResolver {
if (provider.useFactory || provider.useExisting || provider.useClass) {
this._reportError(
new Error(`The ANALYZE_FOR_ENTRY_COMPONENTS token only supports useValue!`), type);
new SyntaxError(`The ANALYZE_FOR_ENTRY_COMPONENTS token only supports useValue!`), type);
return [];
}
if (!provider.multi) {
this._reportError(
new Error(`The ANALYZE_FOR_ENTRY_COMPONENTS token only supports 'multi = true'!`), type);
new SyntaxError(`The ANALYZE_FOR_ENTRY_COMPONENTS token only supports 'multi = true'!`),
type);
return [];
}
@ -893,7 +894,7 @@ export class CompileMetadataResolver {
} else {
if (!q.selector) {
this._reportError(
new Error(
new SyntaxError(
`Can't construct a query for the property "${propertyName}" of "${stringifyType(typeOrFunc)}" since the query selector wasn't defined.`),
typeOrFunc);
}
@ -961,7 +962,7 @@ export function componentModuleUrl(
const scheme = getUrlScheme(moduleId);
return scheme ? moduleId : `package:${moduleId}${MODULE_SUFFIX}`;
} else if (moduleId !== null && moduleId !== void 0) {
throw new Error(
throw new SyntaxError(
`moduleId should be a string in "${stringifyType(type)}". See https://goo.gl/wIDDiL for more information.\n` +
`If you're using Webpack you should inline the template and the styles, see https://goo.gl/X2J8zc.`);
}

View File

@ -24,7 +24,7 @@ import {ProviderElementContext, ProviderViewContext} from '../provider_analyzer'
import {ElementSchemaRegistry} from '../schema/element_schema_registry';
import {CssSelector, SelectorMatcher} from '../selector';
import {isStyleUrlResolvable} from '../style_url_resolver';
import {SyntaxError} from '../util';
import {BindingParser, BoundProperty} from './binding_parser';
import {AttrAst, BoundDirectivePropertyAst, BoundElementPropertyAst, BoundEventAst, BoundTextAst, DirectiveAst, ElementAst, EmbeddedTemplateAst, NgContentAst, PropertyBindingType, ReferenceAst, TemplateAst, TemplateAstVisitor, TextAst, VariableAst, templateVisitAll} from './template_ast';
import {PreparsedElementType, preparseElement} from './template_preparser';
@ -99,7 +99,7 @@ export class TemplateParser {
if (errors.length > 0) {
const errorString = errors.join('\n');
throw new Error(`Template parse errors:\n${errorString}`);
throw new SyntaxError(`Template parse errors:\n${errorString}`);
}
return result.templateAst;

View File

@ -6,8 +6,8 @@
* found in the LICENSE file at https://angular.io/license
*/
import {BaseError} from './facade/errors';
import {isPrimitive, isStrictStringMap} from './facade/lang';
export const MODULE_SUFFIX = '';
const CAMEL_CASE_REGEXP = /([A-Z])/g;
@ -78,3 +78,5 @@ export class SyncAsyncResult<T> {
}
}
}
export class SyntaxError extends BaseError {}