Skip to content

Commit

Permalink
refactor: abstracts errors
Browse files Browse the repository at this point in the history
  • Loading branch information
thetutlage committed Jul 27, 2023
1 parent 311ae4a commit 8512c87
Show file tree
Hide file tree
Showing 6 changed files with 67 additions and 39 deletions.
1 change: 1 addition & 0 deletions index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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'
19 changes: 4 additions & 15 deletions src/connections/abstract_connection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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'

/**
Expand Down Expand Up @@ -245,13 +246,7 @@ export abstract class AbstractConnection<T extends Redis | Cluster> 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])
}

/**
Expand Down Expand Up @@ -291,13 +286,7 @@ export abstract class AbstractConnection<T extends Redis | Cluster> 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])
}

/**
Expand Down
38 changes: 21 additions & 17 deletions src/define_config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<T extends RedisConfig & { connection: keyof T['connections'] }>(
config: T
): T {
export function defineConfig<Connections extends RedisConnectionsList>(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`
)
}

Expand Down
22 changes: 22 additions & 0 deletions src/errors.ts
Original file line number Diff line number Diff line change
@@ -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
)
3 changes: 2 additions & 1 deletion src/redis_manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand Down Expand Up @@ -65,7 +66,7 @@ export default class RedisManager<ConnectionsList extends RedisConnectionsList>
*/
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`)
}

/**
Expand Down
23 changes: 17 additions & 6 deletions tests/define_config.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,27 +12,38 @@ 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'
)
})

test('should throw if connection is not defined inside connections', ({ assert }) => {
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'
)
})
})

0 comments on commit 8512c87

Please sign in to comment.