Skip to content

Commit

Permalink
feat(core): revamp the runtime error message for orphan components to…
Browse files Browse the repository at this point in the history
… include full component info (angular#51919)

The error message now contains the code location of the component. It now looks like: "Error: NG01001: Orphan component found! Trying to render the component Main (at $PROJECT_ROOT/src/main.ts:8) without first loading the NgModule ..."

PR Close angular#51919
  • Loading branch information
pmvald authored and ChellappanRajan committed Jan 23, 2024
1 parent 193403e commit 3661cfc
Show file tree
Hide file tree
Showing 2 changed files with 13 additions and 5 deletions.
4 changes: 3 additions & 1 deletion packages/core/src/render3/deps_tracker/deps_tracker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {getComponentDef, getNgModuleDef, isStandalone} from '../definition';
import {ComponentType, NgModuleScopeInfoFromDecorator, RawScopeInfoFromDecorator} from '../interfaces/definition';
import {isComponent, isDirective, isNgModule, isPipe, verifyStandaloneImport} from '../jit/util';
import {maybeUnwrapFn} from '../util/misc_utils';
import {debugStringifyTypeForError} from '../util/stringify_utils';

import {ComponentDependencies, DepsTrackerApi, NgModuleScope, StandaloneComponentScope} from './api';

Expand Down Expand Up @@ -90,7 +91,8 @@ class DepsTracker implements DepsTrackerApi {
throw new RuntimeError(
RuntimeErrorCode.RUNTIME_DEPS_ORPHAN_COMPONENT,
`Orphan component found! Trying to render the component ${
type.name} without first loading the NgModule that declares it. Make sure that you import the component's NgModule in the NgModule or the standalone component in which you are trying to render this component. Also make sure the way the app is bundled and served always includes the component's NgModule before the component.`);
debugStringifyTypeForError(
type)} without first loading the NgModule that declares it. It is recommended to make this component standalone in order to avoid such confusing cases. If this is not possible now, please import the component's NgModule in the NgModule or the standalone component in which you are trying to render this component. Also make sure the way the app is bundled and served always includes the component's NgModule before the component.`);
}

const scope = this.getNgModuleScope(this.ownerNgModule.get(type)!);
Expand Down
14 changes: 10 additions & 4 deletions packages/core/test/render3/deps_tracker_spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@
* found in the LICENSE file at https://angular.io/license
*/

import {Component, Directive, forwardRef, NgModule, Pipe, Type} from '@angular/core';
import {NgModuleDef} from '@angular/core/src/r3_symbols';
import {ComponentType, NgModuleType} from '@angular/core/src/render3';
import {Component, Directive, forwardRef, NgModule, Pipe} from '@angular/core';

import {NgModuleDef} from '../../src/r3_symbols';
import {ComponentType, NgModuleType, ɵsetClassDebugInfo, ɵɵdefineComponent} from '../../src/render3';
import {TEST_ONLY} from '../../src/render3/deps_tracker/deps_tracker';

const {DepsTracker} = TEST_ONLY;
Expand Down Expand Up @@ -1069,9 +1069,15 @@ describe('runtime dependency tracker', () => {
@Component({})
class MainComponent {
}
ɵsetClassDebugInfo(MainComponent, {
className: 'MainComponent',
filePath: 'main.ts',
lineNumber: 11,
});

expect(() => depsTracker.getComponentDependencies(MainComponent as ComponentType<any>))
.toThrowError(/Orphan component found! Trying to render the component MainComponent/);
.toThrowError(
/Orphan component found! Trying to render the component MainComponent \(at main\.ts\:11\)/);
});

it('should return empty deps if the compilation scope of the declaring module is corrupted',
Expand Down

0 comments on commit 3661cfc

Please sign in to comment.