Skip to content

Commit 4a107ed

Browse files
iterianithePunderWoman
authored andcommitted
refactor(core): Return NOT_FOUND for retrieve instead of null (angular#60358)
This fits within the spec of the retrieve. PR Close angular#60358
1 parent 6407274 commit 4a107ed

File tree

16 files changed

+77
-20
lines changed

16 files changed

+77
-20
lines changed

packages/core/primitives/di/src/not_found.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ export class NotFoundError extends Error {
2727
* Type guard for checking if an unknown value is a NotFound.
2828
*/
2929
export function isNotFound(e: unknown): e is NotFound {
30-
return e === NOT_FOUND || (e as NotFoundError).name === 'ɵNotFound';
30+
return e === NOT_FOUND || (e as NotFoundError)?.name === 'ɵNotFound';
3131
}
3232

3333
/**

packages/core/src/di/injector_compatibility.ts

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import {ProviderToken} from './provider_token';
2121
import type {HostAttributeToken} from './host_attribute_token';
2222
import {
2323
Injector as PrimitivesInjector,
24+
isNotFound,
2425
NotFound,
2526
InjectionToken as PrimitivesInjectionToken,
2627
getCurrentInjector,
@@ -50,12 +51,19 @@ export class RetrievingInjector implements PrimitivesInjector {
5051
retrieve<T>(token: PrimitivesInjectionToken<T>, options: unknown): T | NotFound {
5152
const flags: InternalInjectFlags =
5253
convertToBitFlags(options as InjectOptions | undefined) || InternalInjectFlags.Default;
53-
return (this.injector as BackwardsCompatibleInjector).get(
54-
token as unknown as InjectionToken<T>,
55-
// When a dependency is requested with an optional flag, DI returns null as the default value.
56-
flags & InternalInjectFlags.Optional ? null : undefined,
57-
flags,
58-
) as T;
54+
try {
55+
return (this.injector as BackwardsCompatibleInjector).get(
56+
token as unknown as InjectionToken<T>,
57+
// When a dependency is requested with an optional flag, DI returns null as the default value.
58+
(flags & InternalInjectFlags.Optional ? null : THROW_IF_NOT_FOUND) as T,
59+
flags,
60+
) as T;
61+
} catch (e: any) {
62+
if (isNotFound(e)) {
63+
return e;
64+
}
65+
throw e;
66+
}
5967
}
6068
}
6169

@@ -96,11 +104,15 @@ export function injectInjectorOnly<T>(
96104
} else if (currentInjector === null) {
97105
return injectRootLimpMode(token, undefined, flags);
98106
} else {
99-
const value = currentInjector.retrieve(
100-
token as PrimitivesInjectionToken<T>,
101-
convertToInjectOptions(flags),
102-
) as T;
107+
const options = convertToInjectOptions(flags);
108+
const value = currentInjector.retrieve(token as PrimitivesInjectionToken<T>, options) as T;
103109
ngDevMode && emitInjectEvent(token as Type<unknown>, value, flags);
110+
if (isNotFound(value)) {
111+
if (options.optional) {
112+
return null;
113+
}
114+
throw value;
115+
}
104116
return value;
105117
}
106118
}

packages/core/src/di/null_injector.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,15 @@
66
* found in the LICENSE file at https://angular.dev/license
77
*/
88

9+
import {NotFoundError} from '@angular/core/primitives/di';
910
import {stringify} from '../util/stringify';
1011
import type {Injector} from './injector';
1112
import {THROW_IF_NOT_FOUND} from './injector_compatibility';
1213

1314
export class NullInjector implements Injector {
1415
get(token: any, notFoundValue: any = THROW_IF_NOT_FOUND): any {
1516
if (notFoundValue === THROW_IF_NOT_FOUND) {
16-
const error = new Error(`NullInjectorError: No provider for ${stringify(token)}!`);
17-
error.name = 'NullInjectorError';
17+
const error = new NotFoundError(`NullInjectorError: No provider for ${stringify(token)}!`);
1818
throw error;
1919
}
2020
return notFoundValue;

packages/core/src/di/r3_injector.ts

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ import {
8080
InjectionToken as PrimitivesInjectionToken,
8181
NOT_FOUND,
8282
NotFound,
83+
isNotFound,
8384
} from '@angular/core/primitives/di';
8485

8586
/**
@@ -238,12 +239,19 @@ export class R3Injector extends EnvironmentInjector implements PrimitivesInjecto
238239
retrieve<T>(token: PrimitivesInjectionToken<T>, options?: unknown): T | NotFound {
239240
const flags: InternalInjectFlags =
240241
convertToBitFlags(options as InjectOptions | undefined) || InternalInjectFlags.Default;
241-
return (this as BackwardsCompatibleInjector).get(
242-
token as unknown as InjectionToken<T>,
243-
// When a dependency is requested with an optional flag, DI returns null as the default value.
244-
flags & InternalInjectFlags.Optional ? null : undefined,
245-
flags,
246-
)!;
242+
try {
243+
return (this as BackwardsCompatibleInjector).get(
244+
token as unknown as InjectionToken<T>,
245+
// When a dependency is requested with an optional flag, DI returns null as the default value.
246+
THROW_IF_NOT_FOUND as T,
247+
flags,
248+
);
249+
} catch (e: any) {
250+
if (isNotFound(e)) {
251+
return e;
252+
}
253+
throw e;
254+
}
247255
}
248256

249257
/**
@@ -367,7 +375,8 @@ export class R3Injector extends EnvironmentInjector implements PrimitivesInjecto
367375
: notFoundValue;
368376
return nextInjector.get(token, notFoundValue);
369377
} catch (e: any) {
370-
if (e.name === 'NullInjectorError') {
378+
if (isNotFound(e)) {
379+
// @ts-ignore
371380
const path: any[] = (e[NG_TEMP_TOKEN_PATH] = e[NG_TEMP_TOKEN_PATH] || []);
372381
path.unshift(stringify(token));
373382
if (previousInjector) {

packages/core/test/bundling/animations-standalone/bundle.golden_symbols.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@
106106
"NG_INJ_DEF",
107107
"NG_PIPE_DEF",
108108
"NG_PROV_DEF",
109+
"NOT_FOUND",
109110
"NOT_FOUND2",
110111
"NOT_FOUND_CHECK_ONLY_ELEMENT_INJECTOR",
111112
"NOT_YET",
@@ -123,6 +124,7 @@
123124
"NoopAnimationDriver",
124125
"NoopAnimationPlayer",
125126
"NoopNgZone",
127+
"NotFoundError",
126128
"NullInjector",
127129
"ObjectUnsubscribedError",
128130
"Observable",
@@ -376,6 +378,7 @@
376378
"isLView",
377379
"isNodeMatchingSelector",
378380
"isNodeMatchingSelectorList",
381+
"isNotFound",
379382
"isPlatformServer",
380383
"isPositive",
381384
"isPromise",

packages/core/test/bundling/animations/bundle.golden_symbols.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@
113113
"NG_MOD_DEF",
114114
"NG_PIPE_DEF",
115115
"NG_PROV_DEF",
116+
"NOT_FOUND",
116117
"NOT_FOUND2",
117118
"NOT_FOUND_CHECK_ONLY_ELEMENT_INJECTOR",
118119
"NOT_YET",
@@ -133,6 +134,7 @@
133134
"NoopAnimationDriver",
134135
"NoopAnimationPlayer",
135136
"NoopNgZone",
137+
"NotFoundError",
136138
"NullInjector",
137139
"ObjectUnsubscribedError",
138140
"Observable",
@@ -399,6 +401,7 @@
399401
"isLView",
400402
"isNodeMatchingSelector",
401403
"isNodeMatchingSelectorList",
404+
"isNotFound",
402405
"isPlatformServer",
403406
"isPositive",
404407
"isPromise",

packages/core/test/bundling/cyclic_import/bundle.golden_symbols.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@
8282
"NG_MOD_DEF",
8383
"NG_PIPE_DEF",
8484
"NG_PROV_DEF",
85+
"NOT_FOUND",
8586
"NOT_FOUND2",
8687
"NOT_FOUND_CHECK_ONLY_ELEMENT_INJECTOR",
8788
"NOT_YET",
@@ -98,6 +99,7 @@
9899
"NodeInjectorFactory",
99100
"NoneEncapsulationDomRenderer",
100101
"NoopNgZone",
102+
"NotFoundError",
101103
"NullInjector",
102104
"ObjectUnsubscribedError",
103105
"Observable",
@@ -321,6 +323,7 @@
321323
"isLView",
322324
"isNodeMatchingSelector",
323325
"isNodeMatchingSelectorList",
326+
"isNotFound",
324327
"isPlatformServer",
325328
"isPositive",
326329
"isPromise",

packages/core/test/bundling/defer/bundle.golden_symbols.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@
111111
"NG_TEMPLATE_SELECTOR",
112112
"NG_TEMP_TOKEN_PATH",
113113
"NG_TOKEN_PATH",
114+
"NOT_FOUND",
114115
"NOT_FOUND2",
115116
"NOT_FOUND_CHECK_ONLY_ELEMENT_INJECTOR",
116117
"NOT_YET",
@@ -126,6 +127,7 @@
126127
"NodeInjectorFactory",
127128
"NoneEncapsulationDomRenderer",
128129
"NoopNgZone",
130+
"NotFoundError",
129131
"NullInjector",
130132
"ON_COMPLETE_FNS",
131133
"ObjectUnsubscribedError",
@@ -385,6 +387,7 @@
385387
"isLView",
386388
"isNodeMatchingSelector",
387389
"isNodeMatchingSelectorList",
390+
"isNotFound",
388391
"isPlatformServer",
389392
"isPositive",
390393
"isPromise",

packages/core/test/bundling/forms_reactive/bundle.golden_symbols.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,7 @@
118118
"NG_PROV_DEF",
119119
"NG_VALIDATORS",
120120
"NG_VALUE_ACCESSOR",
121+
"NOT_FOUND",
121122
"NOT_FOUND2",
122123
"NOT_FOUND_CHECK_ONLY_ELEMENT_INJECTOR",
123124
"NOT_YET",
@@ -140,6 +141,7 @@
140141
"NodeInjectorFactory",
141142
"NoneEncapsulationDomRenderer",
142143
"NoopNgZone",
144+
"NotFoundError",
143145
"NullInjector",
144146
"ObjectUnsubscribedError",
145147
"Observable",
@@ -470,6 +472,7 @@
470472
"isListLikeIterable",
471473
"isNodeMatchingSelector",
472474
"isNodeMatchingSelectorList",
475+
"isNotFound",
473476
"isOptionsObj",
474477
"isPlatformServer",
475478
"isPositive",

packages/core/test/bundling/forms_template_driven/bundle.golden_symbols.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@
110110
"NG_PROV_DEF",
111111
"NG_VALIDATORS",
112112
"NG_VALUE_ACCESSOR",
113+
"NOT_FOUND",
113114
"NOT_FOUND2",
114115
"NOT_FOUND_CHECK_ONLY_ELEMENT_INJECTOR",
115116
"NOT_YET",
@@ -135,6 +136,7 @@
135136
"NodeInjectorFactory",
136137
"NoneEncapsulationDomRenderer",
137138
"NoopNgZone",
139+
"NotFoundError",
138140
"NullInjector",
139141
"ObjectUnsubscribedError",
140142
"Observable",
@@ -456,6 +458,7 @@
456458
"isListLikeIterable",
457459
"isNodeMatchingSelector",
458460
"isNodeMatchingSelectorList",
461+
"isNotFound",
459462
"isOptionsObj",
460463
"isPlatformServer",
461464
"isPositive",

0 commit comments

Comments
 (0)