diff --git a/src/errors/faker-error.ts b/src/errors/faker-error.ts new file mode 100644 index 00000000000..e38bdf470fb --- /dev/null +++ b/src/errors/faker-error.ts @@ -0,0 +1,4 @@ +/** + * An error instance that will be thrown by faker. + */ +export class FakerError extends Error {} diff --git a/src/fake.ts b/src/fake.ts index b47755159b2..d478d01e4e1 100644 --- a/src/fake.ts +++ b/src/fake.ts @@ -1,4 +1,5 @@ import type { Faker } from '.'; +import { FakerError } from './errors/faker-error'; /** * Generator method for combining faker methods based on string input. @@ -58,7 +59,7 @@ export class Fake { fake(str: string): string { // if incoming str parameter is not provided, return error message if (typeof str !== 'string' || str.length === 0) { - throw new Error('string parameter is required!'); + throw new FakerError('string parameter is required!'); } // find first matching {{ and }} @@ -88,11 +89,11 @@ export class Fake { const parts = method.split('.'); if (this.faker[parts[0]] == null) { - throw new Error('Invalid module: ' + parts[0]); + throw new FakerError('Invalid module: ' + parts[0]); } if (this.faker[parts[0]][parts[1]] == null) { - throw new Error('Invalid method: ' + parts[0] + '.' + parts[1]); + throw new FakerError('Invalid method: ' + parts[0] + '.' + parts[1]); } // assign the function from the module.function namespace diff --git a/src/faker.ts b/src/faker.ts index 1ace8501ce9..de5c0c426eb 100644 --- a/src/faker.ts +++ b/src/faker.ts @@ -7,6 +7,7 @@ import { Datatype } from './datatype'; import { _Date } from './date'; import type { LocaleDefinition } from './definitions'; import { DEFINITIONS } from './definitions'; +import { FakerError } from './errors/faker-error'; import { Fake } from './fake'; import { Finance } from './finance'; import { Git } from './git'; @@ -83,13 +84,13 @@ export class Faker { constructor(opts: FakerOptions) { if (!opts) { - throw new Error( + throw new FakerError( 'Options with at least one entry in locales must be provided' ); } if (Object.keys(opts.locales ?? {}).length === 0) { - throw new Error( + throw new FakerError( 'At least one entry in locales must be provided in the locales parameter' ); } diff --git a/src/finance.ts b/src/finance.ts index 25d44046158..ea71391dd18 100644 --- a/src/finance.ts +++ b/src/finance.ts @@ -1,4 +1,5 @@ import type { Faker } from '.'; +import { FakerError } from './errors/faker-error'; import type { Helpers } from './helpers'; import ibanLib from './iban'; @@ -329,7 +330,7 @@ export class Finance { } if (!ibanFormat) { - throw new Error('Country code ' + countryCode + ' not supported.'); + throw new FakerError('Country code ' + countryCode + ' not supported.'); } let s = ''; diff --git a/src/index.ts b/src/index.ts index d1c2cb1d63f..984833f5625 100644 --- a/src/index.ts +++ b/src/index.ts @@ -26,6 +26,7 @@ export type { VehicleDefinitions, WordDefinitions, } from './definitions'; +export { FakerError } from './errors/faker-error'; export type { FakerOptions, UsableLocale, UsedLocales } from './faker'; export { Gender } from './name'; export type { GenderType } from './name'; diff --git a/src/mersenne.ts b/src/mersenne.ts index d9044e54441..21f52f6c0ef 100644 --- a/src/mersenne.ts +++ b/src/mersenne.ts @@ -1,3 +1,4 @@ +import { FakerError } from './errors/faker-error'; import Gen from './utils/mersenne'; /** @@ -46,7 +47,9 @@ export class Mersenne { */ seed(S: number): void { if (typeof S !== 'number') { - throw new Error('seed(S) must take numeric argument; is ' + typeof S); + throw new FakerError( + 'seed(S) must take numeric argument; is ' + typeof S + ); } this.gen.initGenrand(S); @@ -60,7 +63,7 @@ export class Mersenne { */ seed_array(A: number[]): void { if (typeof A !== 'object') { - throw new Error( + throw new FakerError( 'seed_array(A) must take array of numbers; is ' + typeof A ); } diff --git a/src/random.ts b/src/random.ts index f41a67fa36d..20d54f5b16b 100644 --- a/src/random.ts +++ b/src/random.ts @@ -1,4 +1,5 @@ import type { Faker } from '.'; +import { FakerError } from './errors/faker-error'; import { deprecated } from './internal/deprecated'; /** @@ -527,7 +528,7 @@ export class Random { } if (charsArray.length === 0) { - throw new Error( + throw new FakerError( 'Unable to generate string, because all possible characters are banned.' ); } diff --git a/src/utils/unique.ts b/src/utils/unique.ts index 78d0fdfc13d..2679b3d86d5 100644 --- a/src/utils/unique.ts +++ b/src/utils/unique.ts @@ -1,3 +1,5 @@ +import { FakerError } from '../errors/faker-error'; + export type RecordKey = string | number | symbol; // global results store @@ -41,7 +43,7 @@ function errorMessage( now - opts.startTime, 'ms' ); - throw new Error( + throw new FakerError( code + ' for uniqueness check \n\nMay not be able to generate any more unique values with current settings. \nTry adjusting maxTime or maxRetries parameters for faker.unique()' ); diff --git a/test/fake.spec.ts b/test/fake.spec.ts index 530d09d2861..bf6a2509fca 100644 --- a/test/fake.spec.ts +++ b/test/fake.spec.ts @@ -1,5 +1,6 @@ import { describe, expect, it } from 'vitest'; import { faker } from '../src'; +import { FakerError } from '../src/errors/faker-error'; describe('fake', () => { describe('fake()', () => { @@ -32,18 +33,18 @@ describe('fake', () => { expect(() => // @ts-expect-error: The parameter is required faker.fake() - ).toThrowError(Error('string parameter is required!')); + ).toThrowError(new FakerError('string parameter is required!')); }); it('does not allow invalid module name', () => { expect(() => faker.fake('{{foo.bar}}')).toThrowError( - Error('Invalid module: foo') + new FakerError('Invalid module: foo') ); }); it('does not allow invalid method name', () => { expect(() => faker.fake('{{address.foo}}')).toThrowError( - Error('Invalid method: address.foo') + new FakerError('Invalid method: address.foo') ); }); diff --git a/test/faker.spec.ts b/test/faker.spec.ts index 24486b48f24..983a31bd9b4 100644 --- a/test/faker.spec.ts +++ b/test/faker.spec.ts @@ -1,5 +1,6 @@ import { beforeEach, describe, expect, it } from 'vitest'; import { faker, Faker } from '../src'; +import { FakerError } from '../src/errors/faker-error'; describe('faker', () => { beforeEach(() => { @@ -12,7 +13,9 @@ describe('faker', () => { // @ts-expect-error: mission options new Faker() ).toThrow( - Error('Options with at least one entry in locales must be provided') + new FakerError( + 'Options with at least one entry in locales must be provided' + ) ); }); @@ -22,7 +25,7 @@ describe('faker', () => { // @ts-expect-error: missing locales new Faker({}) ).toThrow( - Error( + new FakerError( 'At least one entry in locales must be provided in the locales parameter' ) ); diff --git a/test/finance.spec.ts b/test/finance.spec.ts index f5d4521adc6..ce529fe2951 100644 --- a/test/finance.spec.ts +++ b/test/finance.spec.ts @@ -1,5 +1,6 @@ import { afterEach, describe, expect, it } from 'vitest'; import { faker } from '../src'; +import { FakerError } from '../src/errors/faker-error'; import ibanLib from '../src/iban'; import { luhnCheck } from './support/luhnCheck'; @@ -490,7 +491,9 @@ describe('finance', () => { expect(() => faker.finance.iban(false, unsupportedCountryCode) ).toThrowError( - Error(`Country code ${unsupportedCountryCode} not supported.`) + new FakerError( + `Country code ${unsupportedCountryCode} not supported.` + ) ) ); }); diff --git a/test/mersenne.spec.ts b/test/mersenne.spec.ts index e7ca6198966..642731b2488 100644 --- a/test/mersenne.spec.ts +++ b/test/mersenne.spec.ts @@ -1,4 +1,5 @@ import { beforeAll, beforeEach, describe, expect, it } from 'vitest'; +import { FakerError } from '../src/errors/faker-error'; import { Mersenne } from '../src/mersenne'; type SeededRun = { @@ -181,7 +182,9 @@ describe('mersenne twister', () => { // @ts-expect-error: non-integer error 'abc' ) - ).toThrowError(Error('seed(S) must take numeric argument; is string')); + ).toThrowError( + new FakerError('seed(S) must take numeric argument; is string') + ); }); it('should throw an error when attempting to seed() a non-integer', () => { @@ -191,7 +194,7 @@ describe('mersenne twister', () => { 'abc' ) ).toThrowError( - Error('seed_array(A) must take array of numbers; is string') + new FakerError('seed_array(A) must take array of numbers; is string') ); }); }); diff --git a/test/unique.spec.ts b/test/unique.spec.ts index f222b7cea00..fab12ba7002 100644 --- a/test/unique.spec.ts +++ b/test/unique.spec.ts @@ -1,5 +1,6 @@ import { afterEach, describe, expect, it } from 'vitest'; import { faker } from '../src'; +import { FakerError } from '../src/errors/faker-error'; const seededRuns = [ { @@ -120,6 +121,16 @@ describe('unique', () => { }); }).toThrowError(/^Exceeded maxRetries:/); }); + + it('should throw a FakerError instance on error', () => { + expect(() => { + faker.unique(faker.internet.protocol, [], { + maxTime: 5000, + maxRetries: 5, + exclude: ['https', 'http'], + }); + }).toThrowError(FakerError); + }); }); } });