diff --git a/packages/compiler-cli/src/ngtsc/core/src/compiler.ts b/packages/compiler-cli/src/ngtsc/core/src/compiler.ts index e32dd7d9e3..127d7253ad 100644 --- a/packages/compiler-cli/src/ngtsc/core/src/compiler.ts +++ b/packages/compiler-cli/src/ngtsc/core/src/compiler.ts @@ -11,7 +11,7 @@ import * as ts from 'typescript'; import {ComponentDecoratorHandler, DirectiveDecoratorHandler, InjectableDecoratorHandler, NgModuleDecoratorHandler, NoopReferencesRegistry, PipeDecoratorHandler, ReferencesRegistry} from '../../annotations'; import {CycleAnalyzer, ImportGraph} from '../../cycles'; -import {ErrorCode, ngErrorCode} from '../../diagnostics'; +import {COMPILER_ERRORS_WITH_GUIDES, ERROR_DETAILS_PAGE_BASE_URL, ErrorCode, ngErrorCode} from '../../diagnostics'; import {checkForPrivateExports, ReferenceGraph} from '../../entry_point'; import {LogicalFileSystem, resolve} from '../../file_system'; import {AbsoluteModuleStrategy, AliasingHost, AliasStrategy, DefaultImportTracker, ImportRewriter, LocalIdentifierStrategy, LogicalProjectStrategy, ModuleResolver, NoopImportRewriter, PrivateExportAliasingHost, R3SymbolsImportRewriter, Reference, ReferenceEmitStrategy, ReferenceEmitter, RelativePathStrategy, UnifiedModulesAliasingHost, UnifiedModulesStrategy} from '../../imports'; @@ -179,7 +179,8 @@ export class NgCompiler { * Get all Angular-related diagnostics for this compilation. */ getDiagnostics(): ts.Diagnostic[] { - return [...this.getNonTemplateDiagnostics(), ...this.getTemplateDiagnostics()]; + return this.addMessageTextDetails( + [...this.getNonTemplateDiagnostics(), ...this.getTemplateDiagnostics()]); } /** @@ -188,10 +189,26 @@ export class NgCompiler { * If a `ts.SourceFile` is passed, only diagnostics related to that file are returned. */ getDiagnosticsForFile(file: ts.SourceFile, optimizeFor: OptimizeFor): ts.Diagnostic[] { - return [ + return this.addMessageTextDetails([ ...this.getNonTemplateDiagnostics().filter(diag => diag.file === file), ...this.getTemplateDiagnosticsForFile(file, optimizeFor) - ]; + ]); + } + + /** + * Add Angular.io error guide links to diagnostics for this compilation. + */ + private addMessageTextDetails(diagnostics: ts.Diagnostic[]): ts.Diagnostic[] { + return diagnostics.map(diag => { + if (diag.code && COMPILER_ERRORS_WITH_GUIDES.has(ngErrorCode(diag.code))) { + return { + ...diag, + messageText: diag.messageText + + `. Find more at ${ERROR_DETAILS_PAGE_BASE_URL}/NG${ngErrorCode(diag.code)}` + }; + } + return diag; + }); } /** diff --git a/packages/compiler-cli/src/ngtsc/diagnostics/index.ts b/packages/compiler-cli/src/ngtsc/diagnostics/index.ts index 991719e867..fcd7f12098 100644 --- a/packages/compiler-cli/src/ngtsc/diagnostics/index.ts +++ b/packages/compiler-cli/src/ngtsc/diagnostics/index.ts @@ -7,5 +7,5 @@ */ export {FatalDiagnosticError, isFatalDiagnosticError, makeDiagnostic, makeRelatedInformation} from './src/error'; -export {ErrorCode, ngErrorCode} from './src/error_code'; +export {COMPILER_ERRORS_WITH_GUIDES, ERROR_DETAILS_PAGE_BASE_URL, ErrorCode, ngErrorCode} from './src/error_code'; export {replaceTsWithNgInErrors} from './src/util'; diff --git a/packages/compiler-cli/src/ngtsc/diagnostics/src/error_code.ts b/packages/compiler-cli/src/ngtsc/diagnostics/src/error_code.ts index b1e767dcf2..ac7930e3da 100644 --- a/packages/compiler-cli/src/ngtsc/diagnostics/src/error_code.ts +++ b/packages/compiler-cli/src/ngtsc/diagnostics/src/error_code.ts @@ -161,6 +161,27 @@ export enum ErrorCode { INJECTABLE_DUPLICATE_PROV = 9001, } +/** + * @internal + * Base URL for the error details page. + * Keep this value in sync with a similar const in + * `packages/core/src/render3/error_code.ts`. + */ +export const ERROR_DETAILS_PAGE_BASE_URL = 'https://angular.io/errors'; + +/** + * @internal + * Contains a set of error messages that have detailed guides at angular.io. + * Full list of available error guides can be found at https://angular.io/errors + */ +export const COMPILER_ERRORS_WITH_GUIDES = new Set([ + ErrorCode.DECORATOR_ARG_NOT_LITERAL, + ErrorCode.PARAM_MISSING_TOKEN, + ErrorCode.SCHEMA_INVALID_ELEMENT, + ErrorCode.SCHEMA_INVALID_ATTRIBUTE, + ErrorCode.MISSING_REFERENCE_TARGET, +]); + /** * @internal */