From 8512c879970c588149f4e201d05fb9c9c130b212 Mon Sep 17 00:00:00 2001 From: Harminder Virk Date: Thu, 27 Jul 2023 14:35:45 +0530 Subject: [PATCH] refactor: abstracts errors --- index.ts | 1 + src/connections/abstract_connection.ts | 19 +++---------- src/define_config.ts | 38 ++++++++++++++------------ src/errors.ts | 22 +++++++++++++++ src/redis_manager.ts | 3 +- tests/define_config.spec.ts | 23 ++++++++++++---- 6 files changed, 67 insertions(+), 39 deletions(-) create mode 100644 src/errors.ts diff --git a/index.ts b/index.ts index fae4259..c9fa3fa 100644 --- a/index.ts +++ b/index.ts @@ -12,3 +12,4 @@ import './src/types/extended.js' export { defineConfig } from './src/define_config.js' export { stubsRoot } from './stubs/index.js' export { configure } from './configure.js' +export * as errors from './src/errors.js' diff --git a/src/connections/abstract_connection.ts b/src/connections/abstract_connection.ts index d27a9e2..96b53a7 100644 --- a/src/connections/abstract_connection.ts +++ b/src/connections/abstract_connection.ts @@ -8,9 +8,10 @@ */ import { EventEmitter } from 'node:events' -import { Exception } from '@poppinss/utils' import type { Redis, Cluster } from 'ioredis' import { setTimeout } from 'node:timers/promises' + +import * as errors from '../errors.js' import type { HealthReportNode, PubSubChannelHandler, PubSubPatternHandler } from '../types/main.js' /** @@ -245,13 +246,7 @@ export abstract class AbstractConnection extends Even * Disallow multiple subscriptions to a single channel */ if (this.subscriptions.has(channel)) { - throw new Exception( - `Cannot subscribe to "${channel}" channel. Channel already has an active subscription`, - { - code: 'E_MULTIPLE_REDIS_SUBSCRIPTIONS', - status: 500, - } - ) + throw new errors.E_MULTIPLE_REDIS_SUBSCRIPTIONS([channel]) } /** @@ -291,13 +286,7 @@ export abstract class AbstractConnection extends Even * Disallow multiple subscriptions to a single channel */ if (this.psubscriptions.has(pattern)) { - throw new Exception( - `Cannot subscribe to "${pattern}" pattern. Pattern already has an active subscription`, - { - status: 500, - code: 'E_MULTIPLE_REDIS_PSUBSCRIPTIONS', - } - ) + throw new errors.E_MULTIPLE_REDIS_PSUBSCRIPTIONS([pattern]) } /** diff --git a/src/define_config.ts b/src/define_config.ts index b51dbdc..9588778 100644 --- a/src/define_config.ts +++ b/src/define_config.ts @@ -7,34 +7,38 @@ * file that was distributed with this source code. */ -import { InvalidArgumentsException } from '@poppinss/utils' +import { RuntimeException } from '@poppinss/utils' import type { RedisConnectionsList } from './types/main.js' -/** - * Expected shape of the config accepted by the "defineConfig" - * method - */ -type RedisConfig = { - connections: RedisConnectionsList -} - /** * Define config for redis */ -export function defineConfig( - config: T -): T { +export function defineConfig(config: { + connection: keyof Connections + connections: Connections +}): { + connection: keyof Connections + connections: Connections +} { if (!config) { - throw new InvalidArgumentsException('Invalid config. It must be a valid object') + throw new RuntimeException('Invalid config. It must be an object') } if (!config.connections) { - throw new InvalidArgumentsException('Invalid config. Missing property "connections" inside it') + throw new RuntimeException('Missing "connections" property in the redis config file') + } + + if (!config.connection) { + throw new RuntimeException( + 'Missing "connection" property in redis config. Specify a default connection to use' + ) } - if (!config.connection || !(config.connection in config.connections)) { - throw new InvalidArgumentsException( - 'Invalid config. Missing property "connection" or the connection name is not defined inside "connections" object' + if (!config.connections[config.connection]) { + throw new RuntimeException( + `Missing "connections.${String( + config.connection + )}". It is referenced by the "default" redis connection` ) } diff --git a/src/errors.ts b/src/errors.ts new file mode 100644 index 0000000..2790681 --- /dev/null +++ b/src/errors.ts @@ -0,0 +1,22 @@ +/* + * @adonisjs/redis + * + * (c) AdonisJS + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +import { createError } from '@poppinss/utils' + +export const E_MULTIPLE_REDIS_SUBSCRIPTIONS = createError<[string]>( + 'Cannot subscribe to "%s" channel. Channel already has an active subscription', + 'E_MULTIPLE_REDIS_SUBSCRIPTIONS', + 500 +) + +export const E_MULTIPLE_REDIS_PSUBSCRIPTIONS = createError<[string]>( + 'Cannot subscribe to "%s" pattern. Pattern already has an active subscription', + 'E_MULTIPLE_REDIS_PSUBSCRIPTIONS', + 500 +) diff --git a/src/redis_manager.ts b/src/redis_manager.ts index 77c3faf..4f7c03d 100644 --- a/src/redis_manager.ts +++ b/src/redis_manager.ts @@ -7,6 +7,7 @@ * file that was distributed with this source code. */ +import { RuntimeException } from '@poppinss/utils' import RedisConnection from './connections/redis_connection.js' import RedisClusterConnection from './connections/redis_cluster_connection.js' import type { GetConnectionType, RedisConnectionsList } from './types/main.js' @@ -65,7 +66,7 @@ export default class RedisManager */ const config = this.#config.connections[name] if (!config) { - throw new Error(`Redis connection "${name.toString()}" is not defined`) + throw new RuntimeException(`Redis connection "${name.toString()}" is not defined`) } /** diff --git a/tests/define_config.spec.ts b/tests/define_config.spec.ts index f3f75d9..77cf74b 100644 --- a/tests/define_config.spec.ts +++ b/tests/define_config.spec.ts @@ -12,15 +12,15 @@ import { defineConfig } from '../src/define_config.js' test.group('Define Config', () => { test('should throw if no config passed', ({ assert }) => { - // @ts-ignore - assert.throws(defineConfig, 'Invalid config. It must be a valid object') + // @ts-expect-error + assert.throws(defineConfig, 'Invalid config. It must be an object') }) test('should throw if no connections', ({ assert }) => { assert.throws( - // @ts-ignore + // @ts-expect-error () => defineConfig({ connection: 'hey' }), - 'Invalid config. Missing property "connections" inside it' + 'Missing "connections" property in the redis config file' ) }) @@ -28,11 +28,22 @@ test.group('Define Config', () => { assert.throws( () => defineConfig({ - // @ts-ignore + // @ts-expect-error connection: 'hey', connections: {}, }), - 'Invalid config. Missing property "connection" or the connection name is not defined inside "connections" object' + 'Missing "connections.hey". It is referenced by the "default" redis connection' + ) + }) + + test('should throw if default connection is not defined', ({ assert }) => { + assert.throws( + () => + // @ts-expect-error + defineConfig({ + connections: {}, + }), + 'Missing "connection" property in redis config. Specify a default connection to use' ) }) })