Skip to content

Commit fd12220

Browse files
atscottmmalerba
authored andcommitted
fix(core): defer block render failures should report to application error handler (#60149)
This commit updates error reporting of defer blocks to go to the application root error handler rather than the `ErrorHandler` token that may be provided by users. This ensures Angular has control over what happens when these errors are reported. PR Close #60149
1 parent e605433 commit fd12220

File tree

6 files changed

+28
-8
lines changed

6 files changed

+28
-8
lines changed

packages/core/src/defer/rendering.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import {
1616
import {assertLContainer, assertTNodeForLView} from '../render3/assert';
1717
import {ChainedInjector} from '../render3/chained_injector';
1818
import {markViewDirty} from '../render3/instructions/mark_view_dirty';
19-
import {handleError} from '../render3/instructions/shared';
19+
import {handleUncaughtError} from '../render3/instructions/shared';
2020
import {DEHYDRATED_VIEWS, LContainer} from '../render3/interfaces/container';
2121
import {TContainerNode, TNode} from '../render3/interfaces/node';
2222
import {isDestroyed} from '../render3/interfaces/type_checks';
@@ -214,7 +214,7 @@ export function renderDeferBlockState(
214214
try {
215215
applyStateFn(newState, lDetails, lContainer, tNode, hostLView);
216216
} catch (error: unknown) {
217-
handleError(hostLView, error);
217+
handleUncaughtError(hostLView, error);
218218
}
219219
}
220220
}

packages/core/src/defer/triggering.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ import {PendingTasksInternal} from '../pending_tasks';
2525
import {assertLContainer} from '../render3/assert';
2626
import {getComponentDef, getDirectiveDef, getPipeDef} from '../render3/def_getters';
2727
import {getTemplateLocationDetails} from '../render3/instructions/element_validation';
28-
import {handleError} from '../render3/instructions/shared';
28+
import {handleUncaughtError} from '../render3/instructions/shared';
2929
import {DirectiveDefList, PipeDefList} from '../render3/interfaces/definition';
3030
import {TNode} from '../render3/interfaces/node';
3131
import {INJECTOR, LView, TView, TVIEW} from '../render3/interfaces/view';
@@ -261,7 +261,7 @@ export function triggerResourceLoading(
261261
`but no \`@error\` block was configured${templateLocation}. ` +
262262
'Consider using the `@error` block to render an error state.',
263263
);
264-
handleError(lView, error);
264+
handleUncaughtError(lView, error);
265265
}
266266
} else {
267267
tDetails.loadingState = DeferDependenciesLoadingState.COMPLETE;

packages/core/src/render3/instructions/listener.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -310,6 +310,7 @@ function executeListenerWithErrorHandling(
310310
// Only explicitly returning false from a listener should preventDefault
311311
return listenerFn(e) !== false;
312312
} catch (error) {
313+
// TODO(atscott): This should report to the application error handler, not the ErrorHandler on LView injector
313314
handleError(lView, error);
314315
return false;
315316
} finally {

packages/core/src/render3/instructions/shared.ts

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
*/
88

99
import {Injector} from '../../di/injector';
10-
import {ErrorHandler} from '../../error_handler';
10+
import {ErrorHandler, INTERNAL_APPLICATION_ERROR_HANDLER} from '../../error_handler';
1111
import {hasSkipHydrationAttrOnRElement} from '../../hydration/skip_hydration';
1212
import {PRESERVE_HOST_CONTENT, PRESERVE_HOST_CONTENT_DEFAULT} from '../../hydration/tokens';
1313
import {processTextNodeMarkersBeforeHydration} from '../../hydration/utils';
@@ -607,10 +607,25 @@ export function loadComponentRenderer(
607607
}
608608

609609
/** Handles an error thrown in an LView. */
610+
export function handleUncaughtError(lView: LView, error: any): void {
611+
const injector = lView[INJECTOR];
612+
if (!injector) {
613+
return;
614+
}
615+
const errorHandler = injector.get(INTERNAL_APPLICATION_ERROR_HANDLER, null);
616+
errorHandler?.(error);
617+
}
618+
619+
/**
620+
* Handles an error thrown in an LView.
621+
* @deprecated Use handleUncaughtError to report to application error handler
622+
*/
610623
export function handleError(lView: LView, error: any): void {
611624
const injector = lView[INJECTOR];
612-
const errorHandler = injector ? injector.get(ErrorHandler, null) : null;
613-
errorHandler && errorHandler.handleError(error);
625+
if (!injector) {
626+
return;
627+
}
628+
injector.get(ErrorHandler, null)?.handleError(error);
614629
}
615630

616631
/**

packages/core/test/acceptance/defer_spec.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -832,6 +832,7 @@ describe('@defer', () => {
832832
};
833833

834834
TestBed.configureTestingModule({
835+
rethrowApplicationErrors: false,
835836
providers: [{provide: ɵDEFER_BLOCK_DEPENDENCY_INTERCEPTOR, useValue: deferDepsInterceptor}],
836837
});
837838

@@ -892,6 +893,7 @@ describe('@defer', () => {
892893

893894
const reportedErrors: Error[] = [];
894895
TestBed.configureTestingModule({
896+
rethrowApplicationErrors: false,
895897
providers: [
896898
{
897899
provide: ɵDEFER_BLOCK_DEPENDENCY_INTERCEPTOR,
@@ -966,6 +968,7 @@ describe('@defer', () => {
966968

967969
const reportedErrors: Error[] = [];
968970
TestBed.configureTestingModule({
971+
rethrowApplicationErrors: false,
969972
providers: [
970973
{
971974
provide: ɵDEFER_BLOCK_DEPENDENCY_INTERCEPTOR,
@@ -1054,6 +1057,7 @@ describe('@defer', () => {
10541057
}
10551058

10561059
TestBed.configureTestingModule({
1060+
rethrowApplicationErrors: false,
10571061
providers: [
10581062
{provide: ɵDEFER_BLOCK_DEPENDENCY_INTERCEPTOR, useValue: deferDepsInterceptor},
10591063
{

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -342,8 +342,8 @@
342342
"getTNode",
343343
"getTNodeFromLView",
344344
"getTView",
345-
"handleError",
346345
"handleStoppedNotification",
346+
"handleUncaughtError",
347347
"handleUnhandledError",
348348
"hasApplyArgsData",
349349
"hasInSkipHydrationBlockFlag",

0 commit comments

Comments
 (0)