diff --git a/packages/core/test/test_bed_spec.ts b/packages/core/test/test_bed_spec.ts
index 0070e06797..d9da302e95 100644
--- a/packages/core/test/test_bed_spec.ts
+++ b/packages/core/test/test_bed_spec.ts
@@ -267,6 +267,51 @@ describe('TestBed', () => {
TestBed.configureTestingModule({imports: [ProvidesErrorHandler, HelloWorldModule]});
expect(TestBed.get(ErrorHandler)).toEqual(jasmine.any(CustomErrorHandler));
+
+ });
+
+ it('should throw errors in CD', () => {
+ @Component({selector: 'my-comp', template: ''})
+ class MyComp {
+ name !: {hello: string};
+
+ ngOnInit() {
+ // this should throw because this.name is undefined
+ this.name.hello = 'hello';
+ }
+ }
+
+ TestBed.configureTestingModule({declarations: [MyComp]});
+
+ expect(() => {
+ const fixture = TestBed.createComponent(MyComp);
+ fixture.detectChanges();
+ }).toThrowError();
+ });
+
+ // TODO(FW-1245): properly fix issue where errors in listeners aren't thrown and don't cause
+ // tests to fail. This is an issue in both View Engine and Ivy, and may require a breaking
+ // change to completely fix (since simple re-throwing breaks handlers in ngrx, etc).
+ xit('should throw errors in listeners', () => {
+
+ @Component({selector: 'my-comp', template: ''})
+ class MyComp {
+ name !: {hello: string};
+
+ onClick() {
+ // this should throw because this.name is undefined
+ this.name.hello = 'hello';
+ }
+ }
+
+ TestBed.configureTestingModule({declarations: [MyComp]});
+ const fixture = TestBed.createComponent(MyComp);
+ fixture.detectChanges();
+
+ expect(() => {
+ const button = fixture.nativeElement.querySelector('button');
+ button.click();
+ }).toThrowError();
});
onlyInIvy('TestBed should handle AOT pre-compiled Components')
diff --git a/packages/core/testing/src/r3_test_bed_compiler.ts b/packages/core/testing/src/r3_test_bed_compiler.ts
index b5222215ac..aac9429371 100644
--- a/packages/core/testing/src/r3_test_bed_compiler.ts
+++ b/packages/core/testing/src/r3_test_bed_compiler.ts
@@ -6,7 +6,7 @@
* found in the LICENSE file at https://angular.io/license
*/
-import {ApplicationInitStatus, COMPILER_OPTIONS, Compiler, Component, Directive, ErrorHandler, ModuleWithComponentFactories, NgModule, NgModuleFactory, NgZone, Injector, Pipe, PlatformRef, Provider, Type, ɵcompileComponent as compileComponent, ɵcompileDirective as compileDirective, ɵcompileNgModuleDefs as compileNgModuleDefs, ɵcompilePipe as compilePipe, ɵgetInjectableDef as getInjectableDef, ɵNG_COMPONENT_DEF as NG_COMPONENT_DEF, ɵNG_DIRECTIVE_DEF as NG_DIRECTIVE_DEF, ɵNG_INJECTOR_DEF as NG_INJECTOR_DEF, ɵNG_MODULE_DEF as NG_MODULE_DEF, ɵNG_PIPE_DEF as NG_PIPE_DEF, ɵRender3ComponentFactory as ComponentFactory, ɵRender3NgModuleRef as NgModuleRef, ɵɵInjectableDef as InjectableDef, ɵNgModuleFactory as R3NgModuleFactory, ɵNgModuleTransitiveScopes as NgModuleTransitiveScopes, ɵNgModuleType as NgModuleType, ɵDirectiveDef as DirectiveDef, ɵpatchComponentDefWithScope as patchComponentDefWithScope, ɵtransitiveScopesFor as transitiveScopesFor,} from '@angular/core';
+import {ApplicationInitStatus, COMPILER_OPTIONS, Compiler, Component, Directive, ModuleWithComponentFactories, NgModule, NgModuleFactory, NgZone, Injector, Pipe, PlatformRef, Provider, Type, ɵcompileComponent as compileComponent, ɵcompileDirective as compileDirective, ɵcompileNgModuleDefs as compileNgModuleDefs, ɵcompilePipe as compilePipe, ɵgetInjectableDef as getInjectableDef, ɵNG_COMPONENT_DEF as NG_COMPONENT_DEF, ɵNG_DIRECTIVE_DEF as NG_DIRECTIVE_DEF, ɵNG_INJECTOR_DEF as NG_INJECTOR_DEF, ɵNG_MODULE_DEF as NG_MODULE_DEF, ɵNG_PIPE_DEF as NG_PIPE_DEF, ɵRender3ComponentFactory as ComponentFactory, ɵRender3NgModuleRef as NgModuleRef, ɵɵInjectableDef as InjectableDef, ɵNgModuleFactory as R3NgModuleFactory, ɵNgModuleTransitiveScopes as NgModuleTransitiveScopes, ɵNgModuleType as NgModuleType, ɵDirectiveDef as DirectiveDef, ɵpatchComponentDefWithScope as patchComponentDefWithScope, ɵtransitiveScopesFor as transitiveScopesFor,} from '@angular/core';
import {ResourceLoader} from '@angular/compiler';
import {clearResolutionOfComponentResourcesQueue, restoreComponentResolutionQueue, resolveComponentResources, isComponentDefPendingResolution} from '../../src/metadata/resource_loading';
@@ -513,10 +513,6 @@ export class R3TestBedCompiler {
class RootScopeModule {
}
- @NgModule({providers: [{provide: ErrorHandler, useClass: R3TestErrorHandler}]})
- class R3ErrorHandlerModule {
- }
-
const ngZone = new NgZone({enableLongStackTrace: true});
const providers: Provider[] = [
{provide: NgZone, useValue: ngZone},
@@ -524,8 +520,7 @@ export class R3TestBedCompiler {
...this.providers,
...this.providerOverrides,
];
- const imports =
- [RootScopeModule, this.additionalModuleTypes, R3ErrorHandlerModule, this.imports || []];
+ const imports = [RootScopeModule, this.additionalModuleTypes, this.imports || []];
// clang-format off
compileNgModuleDefs(this.testModuleType, {
@@ -633,11 +628,6 @@ function flatten(values: any[], mapFn?: (value: T) => any): T[] {
return out;
}
-/** Error handler used for tests. Rethrows errors rather than logging them out. */
-class R3TestErrorHandler extends ErrorHandler {
- handleError(error: any) { throw error; }
-}
-
class R3TestCompiler implements Compiler {
constructor(private testBed: R3TestBedCompiler) {}