From 3b81c690028a66aec43bab8f1e11dd225446d143 Mon Sep 17 00:00:00 2001 From: crisbeto Date: Fri, 28 Apr 2017 18:35:36 +0200 Subject: [PATCH 1/3] refactor: remove custom error classes * Removes the custom `MdError` class and refactors all of the classes that extended it into functions. * Removes a few of the single-function `*-errors.ts` files and inlines their content. Fixes #4317. --- .../core/compatibility/compatibility.spec.ts | 8 +-- src/lib/core/compatibility/compatibility.ts | 18 +++--- src/lib/core/core.ts | 3 - src/lib/core/errors/error.ts | 12 ---- src/lib/core/portal/portal-errors.ts | 55 +++++++------------ src/lib/core/portal/portal.ts | 26 ++++----- src/lib/dialog/dialog-container.ts | 13 ++++- src/lib/dialog/dialog-errors.ts | 11 ---- src/lib/grid-list/grid-list-errors.ts | 31 ----------- src/lib/grid-list/grid-list.ts | 4 +- src/lib/grid-list/tile-coordinator.ts | 4 +- src/lib/grid-list/tile-styler.ts | 3 +- src/lib/icon/icon-registry.ts | 20 +++++-- src/lib/icon/icon.ts | 9 ++- src/lib/input/input-container-errors.ts | 28 +++------- src/lib/input/input-container.spec.ts | 14 ++--- src/lib/input/input-container.ts | 18 +++--- src/lib/menu/menu-directive.ts | 6 +- src/lib/menu/menu-errors.ts | 35 ++++-------- src/lib/menu/menu-trigger.ts | 4 +- src/lib/select/select-errors.ts | 22 +++----- src/lib/select/select.spec.ts | 6 +- src/lib/select/select.ts | 8 +-- src/lib/sidenav/sidenav.ts | 14 ++--- src/lib/snack-bar/snack-bar-container.ts | 5 +- src/lib/snack-bar/snack-bar-errors.ts | 11 ---- src/lib/tooltip/tooltip-errors.ts | 11 ---- src/lib/tooltip/tooltip.ts | 12 ++-- 28 files changed, 152 insertions(+), 259 deletions(-) delete mode 100644 src/lib/core/errors/error.ts delete mode 100644 src/lib/dialog/dialog-errors.ts delete mode 100644 src/lib/grid-list/grid-list-errors.ts delete mode 100644 src/lib/snack-bar/snack-bar-errors.ts delete mode 100644 src/lib/tooltip/tooltip-errors.ts diff --git a/src/lib/core/compatibility/compatibility.spec.ts b/src/lib/core/compatibility/compatibility.spec.ts index 44c2d9b9a368..8f63f5df74c1 100644 --- a/src/lib/core/compatibility/compatibility.spec.ts +++ b/src/lib/core/compatibility/compatibility.spec.ts @@ -5,7 +5,7 @@ import { NoConflictStyleCompatibilityMode, MAT_ELEMENTS_SELECTOR, MD_ELEMENTS_SELECTOR, - MdCompatibilityInvalidPrefixError, + getMdCompatibilityInvalidPrefixError, } from './compatibility'; import {wrappedErrorMessage} from '../testing/wrapped-error-message'; @@ -34,7 +34,7 @@ describe('Style compatibility', () => { })); it('should throw an error when trying to use the "mat-" prefix', () => { - const expectedError = new MdCompatibilityInvalidPrefixError('mat', 'mat-checkbox'); + const expectedError = getMdCompatibilityInvalidPrefixError('mat', 'mat-checkbox'); expect(() => { TestBed.createComponent(ComponentWithMatCheckbox); @@ -57,7 +57,7 @@ describe('Style compatibility', () => { }); it('should throw an error when trying to use the "md-" prefix', () => { - const expectedError = new MdCompatibilityInvalidPrefixError('md', 'md-checkbox'); + const expectedError = getMdCompatibilityInvalidPrefixError('md', 'md-checkbox'); expect(() => { TestBed.createComponent(ComponentWithMdCheckbox); @@ -75,7 +75,7 @@ describe('Style compatibility', () => { })); it('should throw an error when using the "md-" prefix', () => { - const expectedError = new MdCompatibilityInvalidPrefixError('md', 'md-checkbox'); + const expectedError = getMdCompatibilityInvalidPrefixError('md', 'md-checkbox'); expect(() => { TestBed.createComponent(ComponentWithMdCheckbox); diff --git a/src/lib/core/compatibility/compatibility.ts b/src/lib/core/compatibility/compatibility.ts index 0dfea2d2aa65..d23d9bad36fb 100644 --- a/src/lib/core/compatibility/compatibility.ts +++ b/src/lib/core/compatibility/compatibility.ts @@ -8,7 +8,6 @@ import { InjectionToken, } from '@angular/core'; import {DOCUMENT} from '@angular/platform-browser'; -import {MdError} from '../errors/error'; export const MATERIAL_COMPATIBILITY_MODE = new InjectionToken('md-compatibility-mode'); @@ -16,16 +15,13 @@ export const MATERIAL_COMPATIBILITY_MODE = new InjectionToken('md-compa export const MATERIAL_SANITY_CHECKS = new InjectionToken('md-sanity-checks'); /** - * Exception thrown if the consumer has used an invalid Material prefix on a component. + * Returns an exception to be thrown if the consumer has used + * an invalid Material prefix on a component. * @docs-private */ -export class MdCompatibilityInvalidPrefixError extends MdError { - constructor(prefix: string, nodeName: string) { - super( - `The "${prefix}-" prefix cannot be used in ng-material v1 compatibility mode. ` + - `It was used on an "${nodeName.toLowerCase()}" element.` - ); - } +export function getMdCompatibilityInvalidPrefixError(prefix: string, nodeName: string) { + return new Error(`The "${prefix}-" prefix cannot be used in ng-material v1 compatibility mode. ` + + `It was used on an "${nodeName.toLowerCase()}" element.`); } /** Selector that matches all elements that may have style collisions with AngularJS Material. */ @@ -160,7 +156,7 @@ export class MatPrefixRejector { elementRef: ElementRef) { if (!isCompatibilityMode) { - throw new MdCompatibilityInvalidPrefixError('mat', elementRef.nativeElement.nodeName); + throw getMdCompatibilityInvalidPrefixError('mat', elementRef.nativeElement.nodeName); } } } @@ -173,7 +169,7 @@ export class MdPrefixRejector { elementRef: ElementRef) { if (isCompatibilityMode) { - throw new MdCompatibilityInvalidPrefixError('md', elementRef.nativeElement.nodeName); + throw getMdCompatibilityInvalidPrefixError('md', elementRef.nativeElement.nodeName); } } } diff --git a/src/lib/core/core.ts b/src/lib/core/core.ts index 2cd10dde347b..9fbfec2b55bc 100644 --- a/src/lib/core/core.ts +++ b/src/lib/core/core.ts @@ -76,9 +76,6 @@ export {MdLineModule, MdLine, MdLineSetter} from './line/line'; // Style export * from './style/index'; -// Error -export {MdError} from './errors/error'; - // Misc export {ComponentType} from './overlay/generic-component-type'; diff --git a/src/lib/core/errors/error.ts b/src/lib/core/errors/error.ts deleted file mode 100644 index 3d05518b8b95..000000000000 --- a/src/lib/core/errors/error.ts +++ /dev/null @@ -1,12 +0,0 @@ -// TODO(kara): Revisit why error messages are not being properly set. - -/** - * Wrapper around Error that sets the error message. - * @docs-private - */ -export class MdError extends Error { - constructor(value: string) { - super(); - this.message = value; - } -} diff --git a/src/lib/core/portal/portal-errors.ts b/src/lib/core/portal/portal-errors.ts index 218c481af003..e8db7395a946 100644 --- a/src/lib/core/portal/portal-errors.ts +++ b/src/lib/core/portal/portal-errors.ts @@ -1,63 +1,48 @@ -import {MdError} from '../errors/error'; - /** - * Exception thrown when attempting to attach a null portal to a host. + * Throws an exception when attempting to attach a null portal to a host. * @docs-private */ -export class NullPortalError extends MdError { - constructor() { - super('Must provide a portal to attach'); - } +export function throwNullPortalError() { + throw new Error('Must provide a portal to attach'); } /** - * Exception thrown when attempting to attach a portal to a host that is already attached. + * Throws an exception when attempting to attach a portal to a host that is already attached. * @docs-private */ -export class PortalAlreadyAttachedError extends MdError { - constructor() { - super('Host already has a portal attached'); - } +export function throwPortalAlreadyAttachedError() { + throw new Error('Host already has a portal attached'); } /** - * Exception thrown when attempting to attach a portal to an already-disposed host. + * Throws an exception when attempting to attach a portal to an already-disposed host. * @docs-private */ -export class PortalHostAlreadyDisposedError extends MdError { - constructor() { - super('This PortalHost has already been disposed'); - } +export function throwPortalHostAlreadyDisposedError() { + throw new Error('This PortalHost has already been disposed'); } /** - * Exception thrown when attempting to attach an unknown portal type. + * Throws an exception when attempting to attach an unknown portal type. * @docs-private */ -export class UnknownPortalTypeError extends MdError { - constructor() { - super( - 'Attempting to attach an unknown Portal type. ' + - 'BasePortalHost accepts either a ComponentPortal or a TemplatePortal.'); - } +export function throwUnknownPortalTypeError() { + throw new Error('Attempting to attach an unknown Portal type. BasePortalHost accepts either' + + 'a ComponentPortal or a TemplatePortal.'); } /** - * Exception thrown when attempting to attach a portal to a null host. + * Throws an exception when attempting to attach a portal to a null host. * @docs-private */ -export class NullPortalHostError extends MdError { - constructor() { - super('Attempting to attach a portal to a null PortalHost'); - } +export function throwNullPortalHostError() { + throw new Error('Attempting to attach a portal to a null PortalHost'); } /** - * Exception thrown when attempting to detach a portal that is not attached. - * @docs-private + * Throws an exception when attempting to detach a portal that is not attached. + * @docs-privatew */ -export class NoPortalAttachedError extends MdError { - constructor() { - super('Attempting to detach a portal that is not attached to a host'); - } +export function throwNoPortalAttachedError() { + throw new Error('Attempting to detach a portal that is not attached to a host'); } diff --git a/src/lib/core/portal/portal.ts b/src/lib/core/portal/portal.ts index 97638f872071..b7a09b73c9e6 100644 --- a/src/lib/core/portal/portal.ts +++ b/src/lib/core/portal/portal.ts @@ -6,12 +6,12 @@ import { Injector } from '@angular/core'; import { - NullPortalHostError, - PortalAlreadyAttachedError, - NoPortalAttachedError, - NullPortalError, - PortalHostAlreadyDisposedError, - UnknownPortalTypeError + throwNullPortalHostError, + throwPortalAlreadyAttachedError, + throwNoPortalAttachedError, + throwNullPortalError, + throwPortalHostAlreadyDisposedError, + throwUnknownPortalTypeError } from './portal-errors'; import {ComponentType} from '../overlay/generic-component-type'; @@ -27,11 +27,11 @@ export abstract class Portal { /** Attach this portal to a host. */ attach(host: PortalHost): T { if (host == null) { - throw new NullPortalHostError(); + throwNullPortalHostError(); } if (host.hasAttached()) { - throw new PortalAlreadyAttachedError(); + throwPortalAlreadyAttachedError(); } this._attachedHost = host; @@ -42,7 +42,7 @@ export abstract class Portal { detach(): void { let host = this._attachedHost; if (host == null) { - throw new NoPortalAttachedError(); + throwNoPortalAttachedError(); } this._attachedHost = null; @@ -168,15 +168,15 @@ export abstract class BasePortalHost implements PortalHost { attach(portal: Portal): any { if (!portal) { - throw new NullPortalError(); + throwNullPortalError(); } if (this.hasAttached()) { - throw new PortalAlreadyAttachedError(); + throwPortalAlreadyAttachedError(); } if (this._isDisposed) { - throw new PortalHostAlreadyDisposedError(); + throwPortalHostAlreadyDisposedError(); } if (portal instanceof ComponentPortal) { @@ -187,7 +187,7 @@ export abstract class BasePortalHost implements PortalHost { return this.attachTemplatePortal(portal); } - throw new UnknownPortalTypeError(); + throwUnknownPortalTypeError(); } abstract attachComponentPortal(portal: ComponentPortal): ComponentRef; diff --git a/src/lib/dialog/dialog-container.ts b/src/lib/dialog/dialog-container.ts index acb5c1459b99..86a0ae0b89b5 100644 --- a/src/lib/dialog/dialog-container.ts +++ b/src/lib/dialog/dialog-container.ts @@ -21,9 +21,16 @@ import { import {DOCUMENT} from '@angular/platform-browser'; import {BasePortalHost, ComponentPortal, PortalHostDirective, TemplatePortal} from '../core'; import {MdDialogConfig} from './dialog-config'; -import {MdDialogContentAlreadyAttachedError} from './dialog-errors'; import {FocusTrapFactory, FocusTrap} from '../core/a11y/focus-trap'; +/** + * Throws an exception for the case when a ComponentPortal is + * attached to a DomPortalHost without an origin. + * @docs-private + */ +export function throwMdDialogContentAlreadyAttachedError() { + throw new Error('Attempting to attach dialog content after content is already attached'); +} /** * Internal component that wraps user-provided dialog content. @@ -89,7 +96,7 @@ export class MdDialogContainer extends BasePortalHost { */ attachComponentPortal(portal: ComponentPortal): ComponentRef { if (this._portalHost.hasAttached()) { - throw new MdDialogContentAlreadyAttachedError(); + throwMdDialogContentAlreadyAttachedError(); } this._savePreviouslyFocusedElement(); @@ -102,7 +109,7 @@ export class MdDialogContainer extends BasePortalHost { */ attachTemplatePortal(portal: TemplatePortal): Map { if (this._portalHost.hasAttached()) { - throw new MdDialogContentAlreadyAttachedError(); + throwMdDialogContentAlreadyAttachedError(); } this._savePreviouslyFocusedElement(); diff --git a/src/lib/dialog/dialog-errors.ts b/src/lib/dialog/dialog-errors.ts deleted file mode 100644 index 4dc7428af9d6..000000000000 --- a/src/lib/dialog/dialog-errors.ts +++ /dev/null @@ -1,11 +0,0 @@ -import {MdError} from '../core'; - -/** - * Exception thrown when a ComponentPortal is attached to a DomPortalHost without an origin. - * @docs-private - */ -export class MdDialogContentAlreadyAttachedError extends MdError { - constructor() { - super('Attempting to attach dialog content after content is already attached'); - } -} diff --git a/src/lib/grid-list/grid-list-errors.ts b/src/lib/grid-list/grid-list-errors.ts deleted file mode 100644 index 9f8b955da30b..000000000000 --- a/src/lib/grid-list/grid-list-errors.ts +++ /dev/null @@ -1,31 +0,0 @@ -import {MdError} from '../core'; - -/** - * Exception thrown when cols property is missing from grid-list - * @docs-private - */ -export class MdGridListColsError extends MdError { - constructor() { - super(`md-grid-list: must pass in number of columns. Example: `); - } -} - -/** - * Exception thrown when a tile's colspan is longer than the number of cols in list - * @docs-private - */ -export class MdGridTileTooWideError extends MdError { - constructor(cols: number, listLength: number) { - super(`md-grid-list: tile with colspan ${cols} is wider than grid with cols="${listLength}".`); - } -} - -/** - * Exception thrown when an invalid ratio is passed in as a rowHeight - * @docs-private - */ -export class MdGridListBadRatioError extends MdError { - constructor(value: string) { - super(`md-grid-list: invalid ratio given for row-height: "${value}"`); - } -} diff --git a/src/lib/grid-list/grid-list.ts b/src/lib/grid-list/grid-list.ts index 458974280888..4afb0f83bdc3 100644 --- a/src/lib/grid-list/grid-list.ts +++ b/src/lib/grid-list/grid-list.ts @@ -13,7 +13,6 @@ import { import {MdGridTile} from './grid-tile'; import {TileCoordinator} from './tile-coordinator'; import {TileStyler, FitTileStyler, RatioTileStyler, FixedTileStyler} from './tile-styler'; -import {MdGridListColsError} from './grid-list-errors'; import {Dir} from '../core'; import { coerceToString, @@ -97,7 +96,8 @@ export class MdGridList implements OnInit, AfterContentChecked { /** Throw a friendly error if cols property is missing */ private _checkCols() { if (!this.cols) { - throw new MdGridListColsError(); + throw new Error(`md-grid-list: must pass in number of columns. ` + + `Example: `); } } diff --git a/src/lib/grid-list/tile-coordinator.ts b/src/lib/grid-list/tile-coordinator.ts index b40f00623fc5..eee25638b809 100644 --- a/src/lib/grid-list/tile-coordinator.ts +++ b/src/lib/grid-list/tile-coordinator.ts @@ -1,6 +1,5 @@ import {QueryList} from '@angular/core'; import {MdGridTile} from './grid-tile'; -import {MdGridTileTooWideError} from './grid-list-errors'; /** * Class for determining, from a list of tiles, the (row, col) position of each of those tiles @@ -69,7 +68,8 @@ export class TileCoordinator { /** Finds the next available space large enough to fit the tile. */ private _findMatchingGap(tileCols: number): number { if (tileCols > this.tracker.length) { - throw new MdGridTileTooWideError(tileCols, this.tracker.length); + throw new Error(`md-grid-list: tile with colspan ${tileCols} is wider than ` + + `grid with cols="${this.tracker.length}".`); } // Start index is inclusive, end index is exclusive. diff --git a/src/lib/grid-list/tile-styler.ts b/src/lib/grid-list/tile-styler.ts index a026a9cb8660..1fe21519f578 100644 --- a/src/lib/grid-list/tile-styler.ts +++ b/src/lib/grid-list/tile-styler.ts @@ -1,6 +1,5 @@ import {MdGridTile} from './grid-tile'; import {TileCoordinator} from './tile-coordinator'; -import {MdGridListBadRatioError} from './grid-list-errors'; /** * Sets the style properties for an individual tile, given the position calculated by the @@ -200,7 +199,7 @@ export class RatioTileStyler extends TileStyler { let ratioParts = value.split(':'); if (ratioParts.length !== 2) { - throw new MdGridListBadRatioError(value); + throw new Error(`md-grid-list: invalid ratio given for row-height: "${value}"`); } this.rowHeightRatio = parseFloat(ratioParts[0]) / parseFloat(ratioParts[1]); diff --git a/src/lib/icon/icon-registry.ts b/src/lib/icon/icon-registry.ts index 9f6da9a6d96c..89079e874043 100644 --- a/src/lib/icon/icon-registry.ts +++ b/src/lib/icon/icon-registry.ts @@ -18,6 +18,16 @@ import 'rxjs/add/operator/catch'; import 'rxjs/add/observable/throw'; +/** + * Returns an exception to be thrown in the case when attempting to + * load an icon with a name that cannot be found. + * @docs-private + */ +export function getMdIconNameNotFoundError(iconName: string): Error { + return new Error(`Unable to find icon with the name "${iconName}"`); +} + + /** * Configuration for an icon, including the URL and possibly the cached SVG element. * @docs-private @@ -171,7 +181,7 @@ export class MdIconRegistry { /** * Returns an Observable that produces the icon (as an DOM element) with the given name * and namespace. The icon must have been previously registered with addIcon or addIconSet; - * if not, the Observable will throw an MdIconNameNotFoundError. + * if not, the Observable will throw an error. * * @param name Name of the icon to be retrieved. * @param namespace Namespace in which to look for the icon. @@ -187,7 +197,7 @@ export class MdIconRegistry { if (iconSetConfigs) { return this._getSvgFromIconSetConfigs(name, iconSetConfigs); } - return Observable.throw(new MdIconNameNotFoundError(key)); + return Observable.throw(getMdIconNameNotFoundError(key)); } /** @@ -211,7 +221,7 @@ export class MdIconRegistry { * if found copies the element to a new element. If not found, fetches all icon sets * that have not been cached, and searches again after all fetches are completed. * The returned Observable produces the SVG element if possible, and throws - * MdIconNameNotFoundError if no icon with the specified name can be found. + * an error if no icon with the specified name can be found. */ private _getSvgFromIconSetConfigs(name: string, iconSetConfigs: SvgIconConfig[]): Observable { @@ -251,7 +261,7 @@ export class MdIconRegistry { .map((ignoredResults: any) => { const foundIcon = this._extractIconWithNameFromAnySet(name, iconSetConfigs); if (!foundIcon) { - throw new MdIconNameNotFoundError(name); + throw getMdIconNameNotFoundError(name); } return foundIcon; }); @@ -341,7 +351,7 @@ export class MdIconRegistry { div.innerHTML = str; const svg = div.querySelector('svg') as SVGElement; if (!svg) { - throw new MdIconSvgTagNotFoundError(); + throw new Error(' tag not found'); } return svg; } diff --git a/src/lib/icon/icon.ts b/src/lib/icon/icon.ts index 3f7e1347bf2a..83b1027d1726 100644 --- a/src/lib/icon/icon.ts +++ b/src/lib/icon/icon.ts @@ -11,7 +11,6 @@ import { AfterViewChecked, } from '@angular/core'; import {MdIconRegistry} from './icon-registry'; -import {MdIconNameNotFoundError, MdIconInvalidNameError} from './icon-errors'; /** @@ -113,12 +112,12 @@ export class MdIcon implements OnChanges, OnInit, AfterViewChecked { * The separator for the two fields is ':'. If there is no separator, an empty * string is returned for the icon set and the entire value is returned for * the icon name. If the argument is falsy, returns an array of two empty strings. - * Throws a MdIconInvalidNameError if the name contains two or more ':' separators. + * Throws an error if the name contains two or more ':' separators. * Examples: * 'social:cake' -> ['social', 'cake'] * 'penguin' -> ['', 'penguin'] * null -> ['', ''] - * 'a:b:c' -> (throws MdIconInvalidNameError) + * 'a:b:c' -> (throws Error) */ private _splitIconName(iconName: string): [string, string] { if (!iconName) { @@ -132,7 +131,7 @@ export class MdIcon implements OnChanges, OnInit, AfterViewChecked { case 2: return <[string, string]>parts; default: - throw new MdIconInvalidNameError(iconName); + throw new Error(`Invalid icon name: "${iconName}"`); } } @@ -144,7 +143,7 @@ export class MdIcon implements OnChanges, OnInit, AfterViewChecked { const [namespace, iconName] = this._splitIconName(this.svgIcon); this._mdIconRegistry.getNamedSvgIcon(iconName, namespace).first().subscribe( svg => this._setSvgElement(svg), - (err: MdIconNameNotFoundError) => console.log(`Error retrieving icon: ${err.message}`)); + (err: Error) => console.log(`Error retrieving icon: ${err.message}`)); } } if (this._usingFontIcon()) { diff --git a/src/lib/input/input-container-errors.ts b/src/lib/input/input-container-errors.ts index 90a9337b2a65..50a6a86061f1 100644 --- a/src/lib/input/input-container-errors.ts +++ b/src/lib/input/input-container-errors.ts @@ -1,30 +1,20 @@ -import {MdError} from '../core/errors/error'; - /** @docs-private */ -export class MdInputContainerPlaceholderConflictError extends MdError { - constructor() { - super('Placeholder attribute and child element were both specified.'); - } +export function getMdInputContainerPlaceholderConflictError(): Error { + return new Error('Placeholder attribute and child element were both specified.'); } /** @docs-private */ -export class MdInputContainerUnsupportedTypeError extends MdError { - constructor(type: string) { - super(`Input type "${type}" isn't supported by md-input-container.`); - } +export function getMdInputContainerUnsupportedTypeError(type: string): Error { + return new Error(`Input type "${type}" isn't supported by md-input-container.`); } /** @docs-private */ -export class MdInputContainerDuplicatedHintError extends MdError { - constructor(align: string) { - super(`A hint was already declared for 'align="${align}"'.`); - } +export function getMdInputContainerDuplicatedHintError(align: string): Error { + return new Error(`A hint was already declared for 'align="${align}"'.`); } /** @docs-private */ -export class MdInputContainerMissingMdInputError extends MdError { - constructor() { - super('md-input-container must contain an mdInput directive. Did you forget to add mdInput ' + - 'to the native input or textarea element?'); - } +export function getMdInputContainerMissingMdInputError(): Error { + return new Error('md-input-container must contain an mdInput directive. ' + + 'Did you forget to add mdInput to the native input or textarea element?'); } diff --git a/src/lib/input/input-container.spec.ts b/src/lib/input/input-container.spec.ts index e7c2c3f6ad00..7ce05fc5bc7c 100644 --- a/src/lib/input/input-container.spec.ts +++ b/src/lib/input/input-container.spec.ts @@ -18,9 +18,9 @@ import {PlatformModule} from '../core/platform/index'; import {wrappedErrorMessage} from '../core/testing/wrapped-error-message'; import {dispatchFakeEvent} from '../core/testing/dispatch-events'; import { - MdInputContainerDuplicatedHintError, - MdInputContainerMissingMdInputError, - MdInputContainerPlaceholderConflictError + getMdInputContainerDuplicatedHintError, + getMdInputContainerMissingMdInputError, + getMdInputContainerPlaceholderConflictError } from './input-container-errors'; @@ -242,28 +242,28 @@ describe('MdInputContainer', function () { let fixture = TestBed.createComponent(MdInputContainerInvalidHintTestController); expect(() => fixture.detectChanges()).toThrowError( - wrappedErrorMessage(new MdInputContainerDuplicatedHintError('start'))); + wrappedErrorMessage(getMdInputContainerDuplicatedHintError('start'))); }); it('validates there\'s only one hint label per side (attribute)', () => { let fixture = TestBed.createComponent(MdInputContainerInvalidHint2TestController); expect(() => fixture.detectChanges()).toThrowError( - wrappedErrorMessage(new MdInputContainerDuplicatedHintError('start'))); + wrappedErrorMessage(getMdInputContainerDuplicatedHintError('start'))); }); it('validates there\'s only one placeholder', () => { let fixture = TestBed.createComponent(MdInputContainerInvalidPlaceholderTestController); expect(() => fixture.detectChanges()).toThrowError( - wrappedErrorMessage(new MdInputContainerPlaceholderConflictError())); + wrappedErrorMessage(getMdInputContainerPlaceholderConflictError())); }); it('validates that mdInput child is present', () => { let fixture = TestBed.createComponent(MdInputContainerMissingMdInputTestController); expect(() => fixture.detectChanges()).toThrowError( - wrappedErrorMessage(new MdInputContainerMissingMdInputError())); + wrappedErrorMessage(getMdInputContainerMissingMdInputError())); }); it('validates the type', () => { diff --git a/src/lib/input/input-container.ts b/src/lib/input/input-container.ts index 5000f6d9a7b4..964b203cf4d9 100644 --- a/src/lib/input/input-container.ts +++ b/src/lib/input/input-container.ts @@ -22,10 +22,10 @@ import {coerceBooleanProperty} from '../core'; import {FormGroupDirective, NgControl, NgForm} from '@angular/forms'; import {getSupportedInputTypes} from '../core/platform/features'; import { - MdInputContainerDuplicatedHintError, - MdInputContainerMissingMdInputError, - MdInputContainerPlaceholderConflictError, - MdInputContainerUnsupportedTypeError + getMdInputContainerDuplicatedHintError, + getMdInputContainerMissingMdInputError, + getMdInputContainerPlaceholderConflictError, + getMdInputContainerUnsupportedTypeError } from './input-container-errors'; @@ -234,7 +234,7 @@ export class MdInputDirective { /** Make sure the input is a supported type. */ private _validateType() { if (MD_INPUT_INVALID_TYPES.indexOf(this._type) !== -1) { - throw new MdInputContainerUnsupportedTypeError(this._type); + throw getMdInputContainerUnsupportedTypeError(this._type); } } @@ -357,7 +357,7 @@ export class MdInputContainer implements AfterViewInit, AfterContentInit { ngAfterContentInit() { if (!this._mdInputChild) { - throw new MdInputContainerMissingMdInputError(); + throw getMdInputContainerMissingMdInputError(); } this._processHints(); @@ -408,7 +408,7 @@ export class MdInputContainer implements AfterViewInit, AfterContentInit { */ private _validatePlaceholders() { if (this._mdInputChild.placeholder && this._placeholderChild) { - throw new MdInputContainerPlaceholderConflictError(); + throw getMdInputContainerPlaceholderConflictError(); } } @@ -431,12 +431,12 @@ export class MdInputContainer implements AfterViewInit, AfterContentInit { this._hintChildren.forEach((hint: MdHint) => { if (hint.align == 'start') { if (startHint || this.hintLabel) { - throw new MdInputContainerDuplicatedHintError('start'); + throw getMdInputContainerDuplicatedHintError('start'); } startHint = hint; } else if (hint.align == 'end') { if (endHint) { - throw new MdInputContainerDuplicatedHintError('end'); + throw getMdInputContainerDuplicatedHintError('end'); } endHint = hint; } diff --git a/src/lib/menu/menu-directive.ts b/src/lib/menu/menu-directive.ts index 15efe4620f7c..bc1a0c35c0ec 100644 --- a/src/lib/menu/menu-directive.ts +++ b/src/lib/menu/menu-directive.ts @@ -14,7 +14,7 @@ import { ViewEncapsulation, } from '@angular/core'; import {MenuPositionX, MenuPositionY} from './menu-positions'; -import {MdMenuInvalidPositionX, MdMenuInvalidPositionY} from './menu-errors'; +import {throwMdMenuInvalidPositionX, throwMdMenuInvalidPositionY} from './menu-errors'; import {MdMenuItem} from './menu-item'; import {FocusKeyManager} from '../core/a11y/focus-key-manager'; import {MdMenuPanel} from './menu-panel'; @@ -50,7 +50,7 @@ export class MdMenu implements AfterContentInit, MdMenuPanel, OnDestroy { get xPosition() { return this._xPosition; } set xPosition(value: MenuPositionX) { if (value !== 'before' && value !== 'after') { - throw new MdMenuInvalidPositionX(); + throwMdMenuInvalidPositionX(); } this._xPosition = value; this.setPositionClasses(); @@ -61,7 +61,7 @@ export class MdMenu implements AfterContentInit, MdMenuPanel, OnDestroy { get yPosition() { return this._yPosition; } set yPosition(value: MenuPositionY) { if (value !== 'above' && value !== 'below') { - throw new MdMenuInvalidPositionY(); + throwMdMenuInvalidPositionY(); } this._yPosition = value; this.setPositionClasses(); diff --git a/src/lib/menu/menu-errors.ts b/src/lib/menu/menu-errors.ts index c7d7d4ec3824..caa66addd1dd 100644 --- a/src/lib/menu/menu-errors.ts +++ b/src/lib/menu/menu-errors.ts @@ -1,42 +1,31 @@ -import {MdError} from '../core'; - /** - * Exception thrown when menu trigger doesn't have a valid md-menu instance + * Throws an exception for the case when menu trigger doesn't have a valid md-menu instance * @docs-private */ -export class MdMenuMissingError extends MdError { - constructor() { - super(`md-menu-trigger: must pass in an md-menu instance. +export function throwMdMenuMissingError() { + throw new Error(`md-menu-trigger: must pass in an md-menu instance. Example: - - `); - } + `); } /** - * Exception thrown when menu's xPosition value isn't valid. + * Throws an exception for the case when menu's x-position value isn't valid. * In other words, it doesn't match 'before' or 'after'. * @docs-private */ -export class MdMenuInvalidPositionX extends MdError { - constructor() { - super(`xPosition value must be either 'before' or after'. - Example: - `); - } +export function throwMdMenuInvalidPositionX() { + throw new Error(`x-position value must be either 'before' or after'. + Example: `); } /** - * Exception thrown when menu's yPosition value isn't valid. + * Throws an exception for the case when menu's y-position value isn't valid. * In other words, it doesn't match 'above' or 'below'. * @docs-private */ -export class MdMenuInvalidPositionY extends MdError { - constructor() { - super(`yPosition value must be either 'above' or below'. - Example: - `); - } +export function throwMdMenuInvalidPositionY() { + throw new Error(`y-position value must be either 'above' or below'. + Example: `); } diff --git a/src/lib/menu/menu-trigger.ts b/src/lib/menu/menu-trigger.ts index 3f9c35a35a1c..22e5240d72d0 100644 --- a/src/lib/menu/menu-trigger.ts +++ b/src/lib/menu/menu-trigger.ts @@ -10,7 +10,7 @@ import { ViewContainerRef, } from '@angular/core'; import {MdMenuPanel} from './menu-panel'; -import {MdMenuMissingError} from './menu-errors'; +import {throwMdMenuMissingError} from './menu-errors'; import { isFakeMousedownFromScreenReader, Dir, @@ -191,7 +191,7 @@ export class MdMenuTrigger implements AfterViewInit, OnDestroy { */ private _checkMenu() { if (!this.menu) { - throw new MdMenuMissingError(); + throwMdMenuMissingError(); } } diff --git a/src/lib/select/select-errors.ts b/src/lib/select/select-errors.ts index fcfb2f7ed597..5309f82feccb 100644 --- a/src/lib/select/select-errors.ts +++ b/src/lib/select/select-errors.ts @@ -1,22 +1,18 @@ -import {MdError} from '../core/errors/error'; - /** - * Exception thrown when attempting to change a select's `multiple` option after initialization. + * Returns an exception to be thrown when attempting to change a s + * elect's `multiple` option after initialization. * @docs-private */ -export class MdSelectDynamicMultipleError extends MdError { - constructor() { - super('Cannot change `multiple` mode of select after initialization.'); - } +export function getMdSelectDynamicMultipleError(): Error { + return new Error('Cannot change `multiple` mode of select after initialization.'); } /** - * Exception thrown when attempting to assign a non-array value to a select in `multiple` mode. - * Note that `undefined` and `null` are still valid values to allow for resetting the value. + * Returns an exception to be thrown when attempting to assign a non-array value to a select + * in `multiple` mode. Note that `undefined` and `null` are still valid values to allow for + * resetting the value. * @docs-private */ -export class MdSelectNonArrayValueError extends MdError { - constructor() { - super('Cannot assign truthy non-array value to select in `multiple` mode.'); - } +export function getMdSelectNonArrayValueError(): Error { + return new Error('Cannot assign truthy non-array value to select in `multiple` mode.'); } diff --git a/src/lib/select/select.spec.ts b/src/lib/select/select.spec.ts index 000ebc4c2511..43a4af6673cf 100644 --- a/src/lib/select/select.spec.ts +++ b/src/lib/select/select.spec.ts @@ -13,7 +13,7 @@ import {NoopAnimationsModule} from '@angular/platform-browser/animations'; import {MdSelectModule} from './index'; import {OverlayContainer} from '../core/overlay/overlay-container'; import {MdSelect, MdSelectFloatPlaceholderType} from './select'; -import {MdSelectDynamicMultipleError, MdSelectNonArrayValueError} from './select-errors'; +import {getMdSelectDynamicMultipleError, getMdSelectNonArrayValueError} from './select-errors'; import {MdOption} from '../core/option/option'; import {Dir} from '../core/rtl/dir'; import {DOWN_ARROW, UP_ARROW, ENTER, SPACE} from '../core/keyboard/keycodes'; @@ -1917,13 +1917,13 @@ describe('MdSelect', () => { it('should throw an exception when trying to set a non-array value', async(() => { expect(() => { testInstance.control.setValue('not-an-array'); - }).toThrowError(wrappedErrorMessage(new MdSelectNonArrayValueError())); + }).toThrowError(wrappedErrorMessage(getMdSelectNonArrayValueError())); })); it('should throw an exception when trying to change multiple mode after init', async(() => { expect(() => { testInstance.select.multiple = false; - }).toThrowError(wrappedErrorMessage(new MdSelectDynamicMultipleError())); + }).toThrowError(wrappedErrorMessage(getMdSelectDynamicMultipleError())); })); it('should pass the `multiple` value to all of the option instances', async(() => { diff --git a/src/lib/select/select.ts b/src/lib/select/select.ts index a4f7fb9071bc..5099709a42f6 100644 --- a/src/lib/select/select.ts +++ b/src/lib/select/select.ts @@ -29,8 +29,8 @@ import {coerceBooleanProperty} from '../core/coercion/boolean-property'; import {ConnectedOverlayDirective} from '../core/overlay/overlay-directives'; import {ViewportRuler} from '../core/overlay/position/viewport-ruler'; import {SelectionModel} from '../core/selection/selection'; -import {MdSelectDynamicMultipleError, MdSelectNonArrayValueError} from './select-errors'; - +import {ScrollDispatcher} from '../core/overlay/scroll/scroll-dispatcher'; +import {getMdSelectDynamicMultipleError, getMdSelectNonArrayValueError} from './select-errors'; import 'rxjs/add/observable/merge'; import 'rxjs/add/operator/startWith'; import 'rxjs/add/operator/filter'; @@ -256,7 +256,7 @@ export class MdSelect implements AfterContentInit, OnDestroy, OnInit, ControlVal get multiple(): boolean { return this._multiple; } set multiple(value: boolean) { if (this._selectionModel) { - throw new MdSelectDynamicMultipleError(); + throw getMdSelectDynamicMultipleError(); } this._multiple = coerceBooleanProperty(value); @@ -541,7 +541,7 @@ export class MdSelect implements AfterContentInit, OnDestroy, OnInit, ControlVal const isArray = Array.isArray(value); if (this.multiple && value && !isArray) { - throw new MdSelectNonArrayValueError(); + throw getMdSelectNonArrayValueError(); } if (isArray) { diff --git a/src/lib/sidenav/sidenav.ts b/src/lib/sidenav/sidenav.ts index fa1acb75f05d..6aeee6fac49e 100644 --- a/src/lib/sidenav/sidenav.ts +++ b/src/lib/sidenav/sidenav.ts @@ -14,17 +14,15 @@ import { NgZone, OnDestroy, } from '@angular/core'; -import {Dir, MdError, coerceBooleanProperty} from '../core'; +import {Dir, coerceBooleanProperty} from '../core'; import {FocusTrapFactory, FocusTrap} from '../core/a11y/focus-trap'; import {ESCAPE} from '../core/keyboard/keycodes'; import 'rxjs/add/operator/first'; -/** Exception thrown when two MdSidenav are matching the same side. */ -export class MdDuplicatedSidenavError extends MdError { - constructor(align: string) { - super(`A sidenav was already declared for 'align="${align}"'`); - } +/** Throws an exception when two MdSidenav are matching the same side. */ +export function throwMdDuplicatedSidenavError(align: string) { + throw new Error(`A sidenav was already declared for 'align="${align}"'`); } @@ -421,12 +419,12 @@ export class MdSidenavContainer implements AfterContentInit { for (let sidenav of this._sidenavs.toArray()) { if (sidenav.align == 'end') { if (this._end != null) { - throw new MdDuplicatedSidenavError('end'); + throwMdDuplicatedSidenavError('end'); } this._end = sidenav; } else { if (this._start != null) { - throw new MdDuplicatedSidenavError('start'); + throwMdDuplicatedSidenavError('start'); } this._start = sidenav; } diff --git a/src/lib/snack-bar/snack-bar-container.ts b/src/lib/snack-bar/snack-bar-container.ts index 98aa833daafd..7c31ecbb7624 100644 --- a/src/lib/snack-bar/snack-bar-container.ts +++ b/src/lib/snack-bar/snack-bar-container.ts @@ -22,7 +22,6 @@ import { PortalHostDirective, } from '../core'; import {MdSnackBarConfig} from './snack-bar-config'; -import {MdSnackBarContentAlreadyAttached} from './snack-bar-errors'; import {Observable} from 'rxjs/Observable'; import {Subject} from 'rxjs/Subject'; @@ -85,7 +84,7 @@ export class MdSnackBarContainer extends BasePortalHost implements OnDestroy { /** Attach a component portal as content to this snack bar container. */ attachComponentPortal(portal: ComponentPortal): ComponentRef { if (this._portalHost.hasAttached()) { - throw new MdSnackBarContentAlreadyAttached(); + throw new Error('Attempting to attach snack bar content after content is already attached'); } if (this.snackBarConfig.extraClasses) { @@ -101,7 +100,7 @@ export class MdSnackBarContainer extends BasePortalHost implements OnDestroy { /** Attach a template portal as content to this snack bar container. */ attachTemplatePortal(portal: TemplatePortal): Map { - throw Error('Not yet implemented'); + throw new Error('Not yet implemented'); } /** Handle end of animations, updating the state of the snackbar. */ diff --git a/src/lib/snack-bar/snack-bar-errors.ts b/src/lib/snack-bar/snack-bar-errors.ts deleted file mode 100644 index 44b2ed84a178..000000000000 --- a/src/lib/snack-bar/snack-bar-errors.ts +++ /dev/null @@ -1,11 +0,0 @@ -import {MdError} from '../core'; - -/** - * Error that is thrown when attempting to attach a snack bar that is already attached. - * @docs-private - */ -export class MdSnackBarContentAlreadyAttached extends MdError { - constructor() { - super('Attempting to attach snack bar content after content is already attached'); - } -} diff --git a/src/lib/tooltip/tooltip-errors.ts b/src/lib/tooltip/tooltip-errors.ts deleted file mode 100644 index 58f9ca0c925d..000000000000 --- a/src/lib/tooltip/tooltip-errors.ts +++ /dev/null @@ -1,11 +0,0 @@ -import {MdError} from '../core'; - -/** - * Exception thrown when a tooltip has an invalid position. - * @docs-private - */ -export class MdTooltipInvalidPositionError extends MdError { - constructor(position: string) { - super(`Tooltip position "${position}" is invalid.`); - } -} diff --git a/src/lib/tooltip/tooltip.ts b/src/lib/tooltip/tooltip.ts index acdbd22861ce..3a6bec6e0154 100644 --- a/src/lib/tooltip/tooltip.ts +++ b/src/lib/tooltip/tooltip.ts @@ -27,7 +27,6 @@ import { OriginConnectionPosition, RepositionScrollStrategy, } from '../core'; -import {MdTooltipInvalidPositionError} from './tooltip-errors'; import {Observable} from 'rxjs/Observable'; import {Subject} from 'rxjs/Subject'; import {Dir} from '../core/rtl/dir'; @@ -44,6 +43,11 @@ export const TOUCHEND_HIDE_DELAY = 1500; /** Time in ms to throttle repositioning after scroll events. */ export const SCROLL_THROTTLE_MS = 20; +/** Throws an error if the user supplied an invalid tooltip position. */ +export function throwMdTooltipInvalidPositionError(position: string) { + throw new Error(`Tooltip position "${position}" is invalid.`); +} + /** * Directive that attaches a material design tooltip to the host element. Animates the showing and * hiding of a tooltip provided position (defaults to below the element). @@ -265,7 +269,7 @@ export class MdTooltip implements OnDestroy { return {originX: 'end', originY: 'center'}; } - throw new MdTooltipInvalidPositionError(this.position); + throwMdTooltipInvalidPositionError(this.position); } /** Returns the overlay position based on the user's preference */ @@ -291,7 +295,7 @@ export class MdTooltip implements OnDestroy { return {overlayX: 'start', overlayY: 'center'}; } - throw new MdTooltipInvalidPositionError(this.position); + throwMdTooltipInvalidPositionError(this.position); } /** Updates the tooltip message and repositions the overlay according to the new message length */ @@ -431,7 +435,7 @@ export class TooltipComponent { case 'right': this._transformOrigin = 'left'; break; case 'above': this._transformOrigin = 'bottom'; break; case 'below': this._transformOrigin = 'top'; break; - default: throw new MdTooltipInvalidPositionError(value); + default: throwMdTooltipInvalidPositionError(value); } } From ad02846c49ec5cc54e5e1bb2311014a2ba5959dd Mon Sep 17 00:00:00 2001 From: crisbeto Date: Sat, 29 Apr 2017 00:09:42 +0200 Subject: [PATCH 2/3] chore: restore and deprecate MdError class --- src/lib/core/core.ts | 3 +++ src/lib/core/errors/error.ts | 13 +++++++++++++ 2 files changed, 16 insertions(+) create mode 100644 src/lib/core/errors/error.ts diff --git a/src/lib/core/core.ts b/src/lib/core/core.ts index 9fbfec2b55bc..2cd10dde347b 100644 --- a/src/lib/core/core.ts +++ b/src/lib/core/core.ts @@ -76,6 +76,9 @@ export {MdLineModule, MdLine, MdLineSetter} from './line/line'; // Style export * from './style/index'; +// Error +export {MdError} from './errors/error'; + // Misc export {ComponentType} from './overlay/generic-component-type'; diff --git a/src/lib/core/errors/error.ts b/src/lib/core/errors/error.ts new file mode 100644 index 000000000000..82a1ae44d2c8 --- /dev/null +++ b/src/lib/core/errors/error.ts @@ -0,0 +1,13 @@ +// TODO(kara): Revisit why error messages are not being properly set. + +/** + * Wrapper around Error that sets the error message. + * @docs-private + * @deprecated + */ +export class MdError extends Error { + constructor(value: string) { + super(); + this.message = value; + } +} From 966916b957c50e97afb77535c06e5a2ecce9d174 Mon Sep 17 00:00:00 2001 From: crisbeto Date: Mon, 15 May 2017 20:50:17 +0200 Subject: [PATCH 3/3] chore: remove newly-added errors --- src/lib/core/core.ts | 3 --- src/lib/core/errors/error.ts | 13 ---------- src/lib/datepicker/datepicker.ts | 5 ++-- src/lib/icon/icon-errors.ts | 43 -------------------------------- src/lib/icon/icon-registry.ts | 17 ++++++++----- src/lib/icon/icon.spec.ts | 8 +++--- src/lib/icon/index.ts | 1 - 7 files changed, 18 insertions(+), 72 deletions(-) delete mode 100644 src/lib/core/errors/error.ts delete mode 100644 src/lib/icon/icon-errors.ts diff --git a/src/lib/core/core.ts b/src/lib/core/core.ts index 2cd10dde347b..9fbfec2b55bc 100644 --- a/src/lib/core/core.ts +++ b/src/lib/core/core.ts @@ -76,9 +76,6 @@ export {MdLineModule, MdLine, MdLineSetter} from './line/line'; // Style export * from './style/index'; -// Error -export {MdError} from './errors/error'; - // Misc export {ComponentType} from './overlay/generic-component-type'; diff --git a/src/lib/core/errors/error.ts b/src/lib/core/errors/error.ts deleted file mode 100644 index 82a1ae44d2c8..000000000000 --- a/src/lib/core/errors/error.ts +++ /dev/null @@ -1,13 +0,0 @@ -// TODO(kara): Revisit why error messages are not being properly set. - -/** - * Wrapper around Error that sets the error message. - * @docs-private - * @deprecated - */ -export class MdError extends Error { - constructor(value: string) { - super(); - this.message = value; - } -} diff --git a/src/lib/datepicker/datepicker.ts b/src/lib/datepicker/datepicker.ts index 4ba113254244..2748b75059d3 100644 --- a/src/lib/datepicker/datepicker.ts +++ b/src/lib/datepicker/datepicker.ts @@ -17,7 +17,6 @@ import {OverlayRef} from '../core/overlay/overlay-ref'; import {ComponentPortal} from '../core/portal/portal'; import {OverlayState} from '../core/overlay/overlay-state'; import {Dir} from '../core/rtl/dir'; -import {MdError} from '../core/errors/error'; import {MdDialog} from '../dialog/dialog'; import {MdDialogRef} from '../dialog/dialog-ref'; import {PositionStrategy} from '../core/overlay/position/position-strategy'; @@ -192,7 +191,7 @@ export class MdDatepicker implements OnDestroy { */ _registerInput(input: MdDatepickerInput): void { if (this._datepickerInput) { - throw new MdError('An MdDatepicker can only be associated with a single input.'); + throw new Error('An MdDatepicker can only be associated with a single input.'); } this._datepickerInput = input; this._inputSubscription = @@ -205,7 +204,7 @@ export class MdDatepicker implements OnDestroy { return; } if (!this._datepickerInput) { - throw new MdError('Attempted to open an MdDatepicker with no associated input.'); + throw new Error('Attempted to open an MdDatepicker with no associated input.'); } this.touchUi ? this._openAsDialog() : this._openAsPopup(); diff --git a/src/lib/icon/icon-errors.ts b/src/lib/icon/icon-errors.ts deleted file mode 100644 index 96550575528e..000000000000 --- a/src/lib/icon/icon-errors.ts +++ /dev/null @@ -1,43 +0,0 @@ -import {MdError} from '../core'; - -/** - * Exception thrown when attempting to load an icon with a name that cannot be found. - * @docs-private - */ -export class MdIconNameNotFoundError extends MdError { - constructor(iconName: string) { - super(`Unable to find icon with the name "${iconName}"`); - } -} - -/** - * Exception thrown when attempting to load SVG content that does not contain the expected - * tag. - * @docs-private - */ -export class MdIconSvgTagNotFoundError extends MdError { - constructor() { - super(' tag not found'); - } -} - -/** - * Exception thrown when the consumer attempts to use `` without including @angular/http. - * @docs-private - */ -export class MdIconNoHttpProviderError extends MdError { - constructor() { - super('Could not find Http provider for use with Angular Material icons. ' + - 'Please include the HttpModule from @angular/http in your app imports.'); - } -} - -/** - * Exception thrown when an invalid icon name is passed to an md-icon component. - * @docs-private - */ -export class MdIconInvalidNameError extends MdError { - constructor(iconName: string) { - super(`Invalid icon name: "${iconName}"`); - } -} diff --git a/src/lib/icon/icon-registry.ts b/src/lib/icon/icon-registry.ts index 89079e874043..528f73a75c36 100644 --- a/src/lib/icon/icon-registry.ts +++ b/src/lib/icon/icon-registry.ts @@ -2,11 +2,6 @@ import {Injectable, SecurityContext, Optional, SkipSelf} from '@angular/core'; import {SafeResourceUrl, DomSanitizer} from '@angular/platform-browser'; import {Http} from '@angular/http'; import {Observable} from 'rxjs/Observable'; -import { - MdIconNameNotFoundError, - MdIconSvgTagNotFoundError, - MdIconNoHttpProviderError, -} from './icon-errors'; import 'rxjs/add/observable/forkJoin'; import 'rxjs/add/observable/of'; import 'rxjs/add/operator/map'; @@ -28,6 +23,16 @@ export function getMdIconNameNotFoundError(iconName: string): Error { } +/** + * Returns an exception to be thrown when the consumer attempts to use + * `` without including @angular/http. + * @docs-private + */ +export function getMdIconNoHttpProviderError(): Error { + return new Error('Could not find Http provider for use with Angular Material icons. ' + + 'Please include the HttpModule from @angular/http in your app imports.'); +} + /** * Configuration for an icon, including the URL and possibly the cached SVG element. * @docs-private @@ -377,7 +382,7 @@ export class MdIconRegistry { */ private _fetchUrl(safeUrl: SafeResourceUrl): Observable { if (!this._http) { - throw new MdIconNoHttpProviderError(); + throw getMdIconNoHttpProviderError(); } const url = this._sanitizer.sanitize(SecurityContext.RESOURCE_URL, safeUrl); diff --git a/src/lib/icon/icon.spec.ts b/src/lib/icon/icon.spec.ts index 7b2902d96f91..41570c07470f 100644 --- a/src/lib/icon/icon.spec.ts +++ b/src/lib/icon/icon.spec.ts @@ -4,9 +4,9 @@ import {HttpModule, XHRBackend} from '@angular/http'; import {MockBackend} from '@angular/http/testing'; import {Component} from '@angular/core'; import {MdIconModule} from './index'; -import {MdIconRegistry} from './icon-registry'; -import {MdIconNoHttpProviderError} from './icon-errors'; +import {MdIconRegistry, getMdIconNoHttpProviderError} from './icon-registry'; import {getFakeSvgHttpResponse} from './fake-svgs'; +import {wrappedErrorMessage} from '../core/testing/wrapped-error-message'; /** Returns the CSS classes assigned to an element as a sorted array. */ @@ -414,6 +414,8 @@ describe('MdIcon without HttpModule', () => { })); it('should throw an error when trying to load a remote icon', async() => { + const expectedError = wrappedErrorMessage(getMdIconNoHttpProviderError()); + expect(() => { mdIconRegistry.addSvgIcon('fido', sanitizer.bypassSecurityTrustResourceUrl('dog.svg')); @@ -421,7 +423,7 @@ describe('MdIcon without HttpModule', () => { fixture.componentInstance.iconName = 'fido'; fixture.detectChanges(); - }).toThrowError(MdIconNoHttpProviderError); + }).toThrowError(expectedError); }); }); diff --git a/src/lib/icon/index.ts b/src/lib/icon/index.ts index c26f97c64428..69aafaf239c2 100644 --- a/src/lib/icon/index.ts +++ b/src/lib/icon/index.ts @@ -14,5 +14,4 @@ export class MdIconModule {} export * from './icon'; -export * from './icon-errors'; export * from './icon-registry';