Skip to content

Commit e8c8b69

Browse files
dylhunnatscott
authored andcommitted
fix(forms): Move all remaining errors in Forms to use RuntimeErrorCode. (#46654)
RuntimeErrorCode allows for better tree-shaking, and unique codes for each error. PR Close #46654
1 parent ecd01f9 commit e8c8b69

File tree

8 files changed

+61
-17
lines changed

8 files changed

+61
-17
lines changed

goldens/public-api/forms/errors.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66

77
// @public
88
export const enum RuntimeErrorCode {
9+
// (undocumented)
10+
COMPAREWITH_NOT_A_FN = 1201,
911
// (undocumented)
1012
FORM_ARRAY_NAME_MISSING_PARENT = 1054,
1113
// (undocumented)
@@ -21,6 +23,18 @@ export const enum RuntimeErrorCode {
2123
// (undocumented)
2224
MISSING_CONTROL_VALUE = 1002,
2325
// (undocumented)
26+
NAME_AND_FORM_CONTROL_NAME_MUST_MATCH = 1202,
27+
// (undocumented)
28+
NG_VALUE_ACCESSOR_NOT_PROVIDED = 1200,
29+
// (undocumented)
30+
NGMODEL_IN_FORM_GROUP = 1350,
31+
// (undocumented)
32+
NGMODEL_IN_FORM_GROUP_NAME = 1351,
33+
// (undocumented)
34+
NGMODEL_WITHOUT_NAME = 1352,
35+
// (undocumented)
36+
NGMODELGROUP_IN_FORM_GROUP = 1353,
37+
// (undocumented)
2438
NO_CONTROLS = 1000,
2539
// (undocumented)
2640
WRONG_VALIDATOR_RETURN_TYPE = -1101

packages/forms/src/directives/radio_control_value_accessor.ts

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

9-
import {Directive, ElementRef, forwardRef, Injectable, Injector, Input, NgModule, OnDestroy, OnInit, Renderer2} from '@angular/core';
9+
import {Directive, ElementRef, forwardRef, Injectable, Injector, Input, NgModule, OnDestroy, OnInit, Renderer2, ɵRuntimeError as RuntimeError} from '@angular/core';
10+
11+
import {RuntimeErrorCode} from '../errors';
1012

1113
import {BuiltInControlValueAccessor, ControlValueAccessor, NG_VALUE_ACCESSOR} from './control_value_accessor';
1214
import {NgControl} from './ng_control';
@@ -18,7 +20,7 @@ export const RADIO_VALUE_ACCESSOR: any = {
1820
};
1921

2022
function throwNameError() {
21-
throw new Error(`
23+
throw new RuntimeError(RuntimeErrorCode.NAME_AND_FORM_CONTROL_NAME_MUST_MATCH, `
2224
If you define both a name and a formControlName attribute on your radio button, their values
2325
must match. Ex: <input type="radio" formControlName="food" name="food">
2426
`);

packages/forms/src/directives/select_control_value_accessor.ts

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

9-
import {Directive, ElementRef, forwardRef, Host, Input, OnDestroy, Optional, Renderer2, StaticProvider} from '@angular/core';
9+
import {Directive, ElementRef, forwardRef, Host, Input, OnDestroy, Optional, Renderer2, StaticProvider, ɵRuntimeError as RuntimeError} from '@angular/core';
10+
11+
import {RuntimeErrorCode} from '../errors';
1012

1113
import {BuiltInControlValueAccessor, ControlValueAccessor, NG_VALUE_ACCESSOR} from './control_value_accessor';
1214

15+
1316
export const SELECT_VALUE_ACCESSOR: StaticProvider = {
1417
provide: NG_VALUE_ACCESSOR,
1518
useExisting: forwardRef(() => SelectControlValueAccessor),
@@ -107,7 +110,9 @@ export class SelectControlValueAccessor extends BuiltInControlValueAccessor impl
107110
@Input()
108111
set compareWith(fn: (o1: any, o2: any) => boolean) {
109112
if (typeof fn !== 'function' && (typeof ngDevMode === 'undefined' || ngDevMode)) {
110-
throw new Error(`compareWith must be a function, but received ${JSON.stringify(fn)}`);
113+
throw new RuntimeError(
114+
RuntimeErrorCode.COMPAREWITH_NOT_A_FN,
115+
`compareWith must be a function, but received ${JSON.stringify(fn)}`);
111116
}
112117
this._compareWith = fn;
113118
}

packages/forms/src/directives/select_multiple_control_value_accessor.ts

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

9-
import {Directive, ElementRef, forwardRef, Host, Input, OnDestroy, Optional, Renderer2, StaticProvider} from '@angular/core';
9+
import {Directive, ElementRef, forwardRef, Host, Input, OnDestroy, Optional, Renderer2, StaticProvider, ɵRuntimeError as RuntimeError} from '@angular/core';
10+
11+
import {RuntimeErrorCode} from '../errors';
1012

1113
import {BuiltInControlValueAccessor, ControlValueAccessor, NG_VALUE_ACCESSOR} from './control_value_accessor';
1214

@@ -103,7 +105,9 @@ export class SelectMultipleControlValueAccessor extends BuiltInControlValueAcces
103105
@Input()
104106
set compareWith(fn: (o1: any, o2: any) => boolean) {
105107
if (typeof fn !== 'function' && (typeof ngDevMode === 'undefined' || ngDevMode)) {
106-
throw new Error(`compareWith must be a function, but received ${JSON.stringify(fn)}`);
108+
throw new RuntimeError(
109+
RuntimeErrorCode.COMPAREWITH_NOT_A_FN,
110+
`compareWith must be a function, but received ${JSON.stringify(fn)}`);
107111
}
108112
this._compareWith = fn;
109113
}

packages/forms/src/directives/shared.ts

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

9+
import {ɵRuntimeError as RuntimeError} from '@angular/core';
10+
11+
import {RuntimeErrorCode} from '../errors';
912
import {AbstractControl} from '../model/abstract_model';
1013
import {FormArray} from '../model/form_array';
1114
import {FormControl} from '../model/form_control';
@@ -292,9 +295,10 @@ function _describeControlLocation(dir: AbstractControlDirective): string {
292295

293296
function _throwInvalidValueAccessorError(dir: AbstractControlDirective) {
294297
const loc = _describeControlLocation(dir);
295-
throw new Error(
298+
throw new RuntimeError(
299+
RuntimeErrorCode.NG_VALUE_ACCESSOR_NOT_PROVIDED,
296300
`Value accessor was not provided as an array for form control with ${loc}. ` +
297-
`Check that the \`NG_VALUE_ACCESSOR\` token is configured as a \`multi: true\` provider.`);
301+
`Check that the \`NG_VALUE_ACCESSOR\` token is configured as a \`multi: true\` provider.`);
298302
}
299303

300304
export function isPropertyUpdated(changes: {[key: string]: any}, viewModel: any): boolean {

packages/forms/src/directives/template_driven_errors.ts

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

9+
import {ɵRuntimeError as RuntimeError} from '@angular/core';
10+
11+
import {RuntimeErrorCode} from '../errors';
12+
913
import {formControlNameExample, formGroupNameExample, ngModelGroupExample, ngModelWithFormGroupExample} from './error_examples';
1014

1115

1216
export function modelParentException(): Error {
13-
return new Error(`
17+
return new RuntimeError(RuntimeErrorCode.NGMODEL_IN_FORM_GROUP, `
1418
ngModel cannot be used to register form controls with a parent formGroup directive. Try using
1519
formGroup's partner directive "formControlName" instead. Example:
1620
@@ -24,7 +28,7 @@ export function modelParentException(): Error {
2428
}
2529

2630
export function formGroupNameException(): Error {
27-
return new Error(`
31+
return new RuntimeError(RuntimeErrorCode.NGMODEL_IN_FORM_GROUP_NAME, `
2832
ngModel cannot be used to register form controls with a parent formGroupName or formArrayName directive.
2933
3034
Option 1: Use formControlName instead of ngModel (reactive strategy):
@@ -37,7 +41,8 @@ export function formGroupNameException(): Error {
3741
}
3842

3943
export function missingNameException(): Error {
40-
return new Error(
44+
return new RuntimeError(
45+
RuntimeErrorCode.NGMODEL_WITHOUT_NAME,
4146
`If ngModel is used within a form tag, either the name attribute must be set or the form
4247
control must be defined as 'standalone' in ngModelOptions.
4348
@@ -46,7 +51,7 @@ export function missingNameException(): Error {
4651
}
4752

4853
export function modelGroupParentException(): Error {
49-
return new Error(`
54+
return new RuntimeError(RuntimeErrorCode.NGMODELGROUP_IN_FORM_GROUP, `
5055
ngModelGroup cannot be used with a parent formGroup directive.
5156
5257
Option 1: Use formGroupName instead of ngModelGroup (reactive strategy):

packages/forms/src/errors.ts

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,21 +11,31 @@
1111
* Reserved error code range: 1000-1999.
1212
*/
1313
export const enum RuntimeErrorCode {
14-
// Reactive Forms errors (10xx)
1514

16-
// Basic structure validation errors
15+
// Structure validation errors (10xx)
1716
NO_CONTROLS = 1000,
1817
MISSING_CONTROL = 1001,
1918
MISSING_CONTROL_VALUE = 1002,
2019

20+
// Reactive Forms errors (1050-1099)
2121
FORM_CONTROL_NAME_MISSING_PARENT = 1050,
2222
FORM_CONTROL_NAME_INSIDE_MODEL_GROUP = 1051,
2323
FORM_GROUP_MISSING_INSTANCE = 1052,
2424
FORM_GROUP_NAME_MISSING_PARENT = 1053,
2525
FORM_ARRAY_NAME_MISSING_PARENT = 1054,
2626

27-
// Validators errors
27+
// Validators errors (11xx)
2828
WRONG_VALIDATOR_RETURN_TYPE = -1101,
2929

30-
// Template-driven Forms errors (11xx)
30+
// Value Accessor Errors (12xx)
31+
NG_VALUE_ACCESSOR_NOT_PROVIDED = 1200,
32+
COMPAREWITH_NOT_A_FN = 1201,
33+
NAME_AND_FORM_CONTROL_NAME_MUST_MATCH = 1202,
34+
35+
// Template-driven Forms errors (1350-1399)
36+
NGMODEL_IN_FORM_GROUP = 1350,
37+
NGMODEL_IN_FORM_GROUP_NAME = 1351,
38+
NGMODEL_WITHOUT_NAME = 1352,
39+
NGMODELGROUP_IN_FORM_GROUP = 1353,
40+
3141
}

packages/forms/test/directives_spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ class CustomValidatorDirective implements Validator {
5454
it('should throw when accessor is not provided as array', () => {
5555
expect(() => selectValueAccessor(dir, {} as any[]))
5656
.toThrowError(
57-
'Value accessor was not provided as an array for form control with unspecified name attribute. Check that the \`NG_VALUE_ACCESSOR\` token is configured as a \`multi: true\` provider.');
57+
'NG01200: Value accessor was not provided as an array for form control with unspecified name attribute. Check that the \`NG_VALUE_ACCESSOR\` token is configured as a \`multi: true\` provider.');
5858
});
5959

6060
it('should return the default value accessor when no other provided', () => {

0 commit comments

Comments
 (0)