Skip to content

Commit

Permalink
feat: use more granular error classes for reporting errors
Browse files Browse the repository at this point in the history
  • Loading branch information
weyoss committed May 4, 2024
1 parent b9a2b3d commit 2cc06c1
Show file tree
Hide file tree
Showing 128 changed files with 843 additions and 600 deletions.
11 changes: 11 additions & 0 deletions src/common/redis-keys/errors/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
/*
* Copyright (c)
* Weyoss <weyoss@protonmail.com>
* https://github.com/weyoss
*
* This source code is licensed under the MIT license found in the LICENSE file
* in the root directory of this source tree.
*/

export { RedisKeysInvalidKeyError } from './redis-keys-invalid-key.error.js';
export { RedisKeysError } from './redis-keys.error.js';
12 changes: 12 additions & 0 deletions src/common/redis-keys/errors/redis-keys-invalid-key.error.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/*
* Copyright (c)
* Weyoss <weyoss@protonmail.com>
* https://github.com/weyoss
*
* This source code is licensed under the MIT license found in the LICENSE file
* in the root directory of this source tree.
*/

import { RedisKeysError } from './redis-keys.error.js';

export class RedisKeysInvalidKeyError extends RedisKeysError {}
File renamed without changes.
20 changes: 8 additions & 12 deletions src/common/redis-keys/redis-keys.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
*/

import { IQueueParams } from '../../lib/index.js';
import { RedisKeysError } from './redis-keys.error.js';
import { RedisKeysInvalidKeyError } from './errors/index.js';

// Key segments separator
const keySegmentSeparator = ':';
Expand Down Expand Up @@ -156,31 +156,27 @@ export const redisKeys = {
return makeNamespacedKeys(mainKeys, globalNamespace);
},

validateNamespace(ns: string): string | RedisKeysError {
validateNamespace(ns: string): string | RedisKeysInvalidKeyError {
const validated = this.validateRedisKey(ns);
if (validated === globalNamespace) {
return new RedisKeysError(
`Namespace [${validated}] is reserved. Use another one.`,
);
return new RedisKeysInvalidKeyError();
}
return validated;
},

validateRedisKey(key: string | null | undefined): string | RedisKeysError {
validateRedisKey(
key: string | null | undefined,
): string | RedisKeysInvalidKeyError {
if (!key || !key.length) {
return new RedisKeysError(
'Invalid Redis key. Expected be a non empty string.',
);
return new RedisKeysInvalidKeyError();
}
const lowerCase = key.toLowerCase();
const filtered = lowerCase.replace(
/(?:[a-z][a-z0-9]?)+(?:[-_.]?[a-z0-9])*/,
'',
);
if (filtered.length) {
return new RedisKeysError(
'Invalid Redis key. Valid characters are letters (a-z) and numbers (0-9). (-_) are allowed between alphanumerics. Use a dot (.) to denote hierarchies.',
);
return new RedisKeysInvalidKeyError();
}
return lowerCase;
},
Expand Down
12 changes: 12 additions & 0 deletions src/config/errors/configuration-message-queue-size.error.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/*
* Copyright (c)
* Weyoss <weyoss@protonmail.com>
* https://github.com/weyoss
*
* This source code is licensed under the MIT license found in the LICENSE file
* in the root directory of this source tree.
*/

import { ConfigurationError } from './configuration.error.js';

export class ConfigurationMessageQueueSizeError extends ConfigurationError {}
12 changes: 12 additions & 0 deletions src/config/errors/configuration-message-store-expire.error.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/*
* Copyright (c)
* Weyoss <weyoss@protonmail.com>
* https://github.com/weyoss
*
* This source code is licensed under the MIT license found in the LICENSE file
* in the root directory of this source tree.
*/

import { ConfigurationError } from './configuration.error.js';

export class ConfigurationMessageStoreExpireError extends ConfigurationError {}
12 changes: 12 additions & 0 deletions src/config/errors/configuration-namespace.error.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/*
* Copyright (c)
* Weyoss <weyoss@protonmail.com>
* https://github.com/weyoss
*
* This source code is licensed under the MIT license found in the LICENSE file
* in the root directory of this source tree.
*/

import { ConfigurationError } from './configuration.error.js';

export class ConfigurationNamespaceError extends ConfigurationError {}
File renamed without changes.
13 changes: 13 additions & 0 deletions src/config/errors/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/*
* Copyright (c)
* Weyoss <weyoss@protonmail.com>
* https://github.com/weyoss
*
* This source code is licensed under the MIT license found in the LICENSE file
* in the root directory of this source tree.
*/

export { ConfigurationError } from './configuration.error.js';
export { ConfigurationMessageStoreExpireError } from './configuration-message-store-expire.error.js';
export { ConfigurationMessageQueueSizeError } from './configuration-message-queue-size.error.js';
export { ConfigurationNamespaceError } from './configuration-namespace.error.js';
1 change: 1 addition & 0 deletions src/config/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,6 @@
* in the root directory of this source tree.
*/

export * from './errors/index.js';
export * from './types/index.js';
export * from './configuration.js';
7 changes: 4 additions & 3 deletions src/config/messages/store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ import {
IMessagesConfigStorageOptionsRequired,
IMessagesConfigStorageRequired,
} from '../../lib/index.js';
import { ConfigurationError } from '../configuration.error.js';
import { ConfigurationMessageQueueSizeError } from '../errors/configuration-message-queue-size.error.js';
import { ConfigurationMessageStoreExpireError } from '../errors/configuration-message-store-expire.error.js';
import { IRedisSMQConfig } from '../types/index.js';

function getMessageStorageConfig(
Expand Down Expand Up @@ -43,11 +44,11 @@ function getMessageStorageParams(
}
const queueSize = Number(params.queueSize ?? 0);
if (isNaN(queueSize) || queueSize < 0) {
throw new ConfigurationError(`Parameter [queueSize] should be >= 0`);
throw new ConfigurationMessageQueueSizeError();
}
const expire = Number(params.expire ?? 0);
if (isNaN(expire) || expire < 0) {
throw new ConfigurationError(`Parameter [expire] should be >= 0`);
throw new ConfigurationMessageStoreExpireError();
}
return {
store: true,
Expand Down
3 changes: 2 additions & 1 deletion src/config/namespace.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,14 @@
*/

import { redisKeys } from '../common/redis-keys/redis-keys.js';
import { ConfigurationNamespaceError } from './errors/configuration-namespace.error.js';
import { IRedisSMQConfig } from './types/index.js';

const defaultNamespace = 'default';

export default function Namespace(userConfig: IRedisSMQConfig): string {
if (!userConfig.namespace) return defaultNamespace;
const ns = redisKeys.validateNamespace(userConfig.namespace);
if (ns instanceof Error) throw ns;
if (ns instanceof Error) throw new ConfigurationNamespaceError();
return ns;
}
16 changes: 12 additions & 4 deletions src/lib/consumer-groups/_/_delete-consumer-group.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,10 @@ import { async, ICallback, IEventBus, IRedisClient } from 'redis-smq-common';
import { TRedisSMQEvent } from '../../../common/index.js';
import { ELuaScriptName } from '../../../common/redis-client/scripts/scripts.js';
import { redisKeys } from '../../../common/redis-keys/redis-keys.js';
import { ConsumerGroupDeleteError } from '../../consumer/index.js';
import { EQueueProperty, EQueueType, IQueueParams } from '../../queue/index.js';
import { ConsumerGroupsConsumerGroupNotEmptyError } from '../errors/consumer-groups-consumer-group-not-empty.error.js';
import { ConsumerGroupsQueueNotFoundError } from '../errors/consumer-groups-queue-not-found.error.js';
import { ConsumerGroupsError } from '../errors/consumer-groups.error.js';

export function _deleteConsumerGroup(
redisClient: IRedisClient,
Expand Down Expand Up @@ -47,9 +49,15 @@ export function _deleteConsumerGroup(
],
(err, reply) => {
if (err) cb(err);
else if (reply !== 'OK')
cb(new ConsumerGroupDeleteError(String(reply)));
else {
else if (reply !== 'OK') {
if (reply === 'QUEUE_NOT_FOUND') {
cb(new ConsumerGroupsQueueNotFoundError());
} else if (reply === 'CONSUMER_GROUP_NOT_EMPTY') {
cb(new ConsumerGroupsConsumerGroupNotEmptyError());
} else {
cb(new ConsumerGroupsError());
}
} else {
eventBus.emit('queue.consumerGroupDeleted', queue, groupId);
cb();
}
Expand Down
3 changes: 2 additions & 1 deletion src/lib/consumer-groups/_/_save-consumer-group.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { ICallback, IEventBus, IRedisClient } from 'redis-smq-common';
import { TRedisSMQEvent } from '../../../common/index.js';
import { redisKeys } from '../../../common/redis-keys/redis-keys.js';
import { IQueueParams } from '../../queue/index.js';
import { ConsumerGroupsInvalidGroupIdError } from '../errors/consumer-groups-invalid-group-id.error.js';

export function _saveConsumerGroup(
redisClient: IRedisClient,
Expand All @@ -20,7 +21,7 @@ export function _saveConsumerGroup(
cb: ICallback<number>,
): void {
const gid = redisKeys.validateRedisKey(groupId);
if (gid instanceof Error) cb(gid);
if (gid instanceof Error) cb(new ConsumerGroupsInvalidGroupIdError());
else {
const { keyQueueConsumerGroups } = redisKeys.getQueueKeys(queue, gid);
redisClient.sadd(keyQueueConsumerGroups, gid, (err, reply) => {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/*
* Copyright (c)
* Weyoss <weyoss@protonmail.com>
* https://github.com/weyoss
*
* This source code is licensed under the MIT license found in the LICENSE file
* in the root directory of this source tree.
*/

import { ConsumerGroupsError } from './consumer-groups.error.js';

export class ConsumerGroupsConsumerGroupNotEmptyError extends ConsumerGroupsError {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/*
* Copyright (c)
* Weyoss <weyoss@protonmail.com>
* https://github.com/weyoss
*
* This source code is licensed under the MIT license found in the LICENSE file
* in the root directory of this source tree.
*/

import { ConsumerGroupsError } from './consumer-groups.error.js';

export class ConsumerGroupsInvalidGroupIdError extends ConsumerGroupsError {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/*
* Copyright (c)
* Weyoss <weyoss@protonmail.com>
* https://github.com/weyoss
*
* This source code is licensed under the MIT license found in the LICENSE file
* in the root directory of this source tree.
*/

import { ConsumerGroupsError } from './consumer-groups.error.js';

export class ConsumerGroupsQueueNotFoundError extends ConsumerGroupsError {}
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,4 @@

import { RedisSMQError } from 'redis-smq-common';

export class EventBusLockError extends RedisSMQError {}
export class ConsumerGroupsError extends RedisSMQError {}
13 changes: 13 additions & 0 deletions src/lib/consumer-groups/errors/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/*
* Copyright (c)
* Weyoss <weyoss@protonmail.com>
* https://github.com/weyoss
*
* This source code is licensed under the MIT license found in the LICENSE file
* in the root directory of this source tree.
*/

export { ConsumerGroupsError } from './consumer-groups.error.js';
export { ConsumerGroupsQueueNotFoundError } from './consumer-groups-queue-not-found.error.js';
export { ConsumerGroupsConsumerGroupNotEmptyError } from './consumer-groups-consumer-group-not-empty.error.js';
export { ConsumerGroupsInvalidGroupIdError } from './consumer-groups-invalid-group-id.error.js';
1 change: 1 addition & 0 deletions src/lib/consumer-groups/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,4 @@
*/

export * from './consumer-groups.js';
export * from './errors/index.js';
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/*
* Copyright (c)
* Weyoss <weyoss@protonmail.com>
* https://github.com/weyoss
*
* This source code is licensed under the MIT license found in the LICENSE file
* in the root directory of this source tree.
*/

import { ConsumerError } from './consumer.error.js';

export class ConsumerConsumeMessageHandlerAlreadyExistsError extends ConsumerError {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/*
* Copyright (c)
* Weyoss <weyoss@protonmail.com>
* https://github.com/weyoss
*
* This source code is licensed under the MIT license found in the LICENSE file
* in the root directory of this source tree.
*/

import { ConsumerError } from './consumer.error.js';

export class ConsumerConsumerGroupIdNotSupportedError extends ConsumerError {}
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,4 @@

import { ConsumerError } from './consumer.error.js';

export class ConsumerGroupDeleteError extends ConsumerError {}
export class ConsumerConsumerGroupIdRequiredError extends ConsumerError {}
18 changes: 0 additions & 18 deletions src/lib/consumer/errors/consumer-group-id-not-supported.error.ts

This file was deleted.

18 changes: 0 additions & 18 deletions src/lib/consumer/errors/consumer-group-id-required.error.ts

This file was deleted.

This file was deleted.

7 changes: 3 additions & 4 deletions src/lib/consumer/errors/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
*/

export { ConsumerError } from './consumer.error.js';
export { ConsumerMessageHandlerAlreadyExistsError } from './consumer-message-handler-already-exists.error.js';
export { ConsumerGroupDeleteError } from './consumer-group-delete.error.js';
export { ConsumerGroupIdNotSupportedError } from './consumer-group-id-not-supported.error.js';
export { ConsumerGroupIdRequiredError } from './consumer-group-id-required.error.js';
export { ConsumerConsumeMessageHandlerAlreadyExistsError } from './consumer-consume-message-handler-already-exists.error.js';
export { ConsumerConsumerGroupIdNotSupportedError } from './consumer-consumer-group-id-not-supported.error.js';
export { ConsumerConsumerGroupIdRequiredError } from './consumer-consumer-group-id-required.error.js';
Loading

0 comments on commit 2cc06c1

Please sign in to comment.