Skip to content

Commit

Permalink
refactor(core): improve an error message when `ENVIRONMENT_INITIALIZE…
Browse files Browse the repository at this point in the history
…R` is not a multi provider (#46829)

Currently if the `ENVIRONMENT_INITIALIZER` token is not configured with `multi: true` flag, the code fails while trying to iterate over the value. This commit checks whether the `ENVIRONMENT_INITIALIZER` token value type is an array and throws a helpful error message.

PR Close #46829
  • Loading branch information
AndrewKushnir authored and jessicajaniuk committed Jul 13, 2022
1 parent 8e2fc3e commit 481dc8d
Show file tree
Hide file tree
Showing 4 changed files with 26 additions and 1 deletion.
2 changes: 2 additions & 0 deletions goldens/public-api/core/errors.md
Expand Up @@ -47,6 +47,8 @@ export const enum RuntimeErrorCode {
// (undocumented)
INVALID_INJECTION_TOKEN = 204,
// (undocumented)
INVALID_MULTI_PROVIDER = 209,
// (undocumented)
MISSING_GENERATED_DEF = 906,
// (undocumented)
MISSING_INJECTION_CONTEXT = -203,
Expand Down
8 changes: 8 additions & 0 deletions packages/core/src/di/r3_injector.ts
Expand Up @@ -247,6 +247,14 @@ export class R3Injector extends EnvironmentInjector {
const previousInjectImplementation = setInjectImplementation(undefined);
try {
const initializers = this.get(ENVIRONMENT_INITIALIZER.multi, EMPTY_ARRAY, InjectFlags.Self);
if (ngDevMode && !Array.isArray(initializers)) {
throw new RuntimeError(
RuntimeErrorCode.INVALID_MULTI_PROVIDER,
'Unexpected type of the `ENVIRONMENT_INITIALIZER` token value ' +
`(expected an array, but got ${typeof initializers}). ` +
'Please check that the `ENVIRONMENT_INITIALIZER` token is configured as a ' +
'`multi: true` provider.');
}
for (const initializer of initializers) {
initializer();
}
Expand Down
1 change: 1 addition & 0 deletions packages/core/src/errors.ts
Expand Up @@ -32,6 +32,7 @@ export const enum RuntimeErrorCode {
INJECTOR_ALREADY_DESTROYED = 205,
PROVIDER_IN_WRONG_CONTEXT = 207,
MISSING_INJECTION_TOKEN = 208,
INVALID_MULTI_PROVIDER = 209,

// Template Errors
MULTIPLE_COMPONENTS_MATCH = -300,
Expand Down
16 changes: 15 additions & 1 deletion packages/core/test/acceptance/environment_injector_spec.ts
Expand Up @@ -88,7 +88,7 @@ describe('environment injector', () => {
expect(cRef.instance.service).toBeInstanceOf(Service);
});

it('should support the ENVIRONMENT_INITIALIZER muli-token', () => {
it('should support the ENVIRONMENT_INITIALIZER multi-token', () => {
let initialized = false;
createEnvironmentInjector([{
provide: ENVIRONMENT_INITIALIZER,
Expand All @@ -99,6 +99,20 @@ describe('environment injector', () => {
expect(initialized).toBeTrue();
});

it('should throw when the ENVIRONMENT_INITIALIZER is not a multi-token', () => {
const parentEnvInjector = TestBed.inject(EnvironmentInjector);
const providers = [{
provide: ENVIRONMENT_INITIALIZER,
useValue: () => {},
}];
expect(() => createEnvironmentInjector(providers, parentEnvInjector))
.toThrowError(
'NG0209: Unexpected type of the `ENVIRONMENT_INITIALIZER` token value ' +
'(expected an array, but got function). ' +
'Please check that the `ENVIRONMENT_INITIALIZER` token is configured as ' +
'a `multi: true` provider.');
});

it('should adopt environment-scoped providers', () => {
const injector = createEnvironmentInjector([]);
const EnvScopedToken = new InjectionToken('env-scoped token', {
Expand Down

0 comments on commit 481dc8d

Please sign in to comment.