Skip to content

Commit c937f3d

Browse files
committedMay 30, 2020
Add strict config validations with error messages
1 parent 26c0b73 commit c937f3d

File tree

6 files changed

+61
-10
lines changed

6 files changed

+61
-10
lines changed
 

‎package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
"main": "lib/index.js",
66
"scripts": {
77
"start": "concurrently -r \"npm run -s start:src\" \"npm run -s start:ui\"",
8-
"start:src": "ts-node-dev --respawn --transpileOnly src -- --config \".conf.json\"",
8+
"start:src": "ts-node-dev --respawn --transpileOnly src -- --debug --config \".conf.json\"",
99
"start:ui": "cd ui && npm start",
1010
"build": "rimraf lib && npm run -s build:src && npm run -s build:ui",
1111
"build:src": "tsc",

‎src/handler.ts

+8-3
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,11 @@ export class QueueHandler {
55
private progressCache: {[id: string]: number} = {};
66

77
constructor(config: QueueConfig, private broadcast: (event: string, ...data: any[]) => boolean) {
8-
this.queue = new bull(config.name, config.options);
8+
if (config.url) {
9+
this.queue = bull(config.name, config.url, config.options);
10+
} else {
11+
this.queue = bull(config.name, config.options);
12+
}
913
this.setupListeners();
1014
}
1115

@@ -17,7 +21,7 @@ export class QueueHandler {
1721
console.log('Broadcasting job counts');
1822
this.getJobCounts()
1923
.then(jobCounts => broadcast('job-counts', jobCounts))
20-
.catch(err => console.log(err));
24+
.catch(err => console.error(err));
2125
}
2226

2327
async fetchJob(jobId: string) {
@@ -118,5 +122,6 @@ export class QueueHandler {
118122

119123
export interface QueueConfig {
120124
name: string;
121-
options: QueueOptions
125+
url?: string;
126+
options?: QueueOptions
122127
}

‎src/index.ts

+4-3
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,18 @@
11
#!/usr/bin/env node
22

33
import minimist from 'minimist';
4-
import fs from 'fs';
4+
import { setupLoggers, loadQueueConfigs } from './utils';
55
import { Server } from './server';
66

77
const args = minimist(process.argv.slice(2));
88

9+
setupLoggers(args.debug);
10+
911
if (!args.config) throw new Error('No config file provided. Please provide a config file with the `--config` parameter.');
10-
if (!fs.existsSync(args.config)) throw new Error('Config file provided not found. Please make sure the path is correct.');
1112

1213
Server.start({
1314
serverConfig: {
1415
port: parseInt(args.port || '3000')
1516
},
16-
queueConfigs: JSON.parse(fs.readFileSync(args.config, 'utf-8'))
17+
queueConfigs: loadQueueConfigs(args.config)
1718
});

‎src/server.ts

+4-2
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,17 @@ import http from 'http';
22
import path from 'path';
33
import express from 'express';
44
import socketio from 'socket.io';
5-
import { QueueHandler, QueueConfig } from './handler';
65
import { JobStatus } from 'bull';
6+
import { EventEmitter } from 'events';
7+
import { QueueHandler, QueueConfig } from './handler';
78

89
export class Server {
910
static start(appConfig: AppConfig) {
1011
const app = express();
1112
const server = http.createServer(app);
1213
const io = socketio(server);
1314

15+
EventEmitter.defaultMaxListeners = 15;
1416
const queueHandlers = Object.keys(appConfig.queueConfigs).reduce((handlers, host) => {
1517
appConfig.queueConfigs[host]
1618
.forEach(config => {
@@ -75,7 +77,7 @@ export class Server {
7577
})
7678

7779
server.listen(appConfig.serverConfig.port, () => {
78-
console.log('Server listening to', appConfig.serverConfig.port);
80+
console.info('Server listening to', appConfig.serverConfig.port);
7981
});
8082
}
8183
}

‎src/utils.ts

+42
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import fs from 'fs';
2+
import { QueueConfig } from './handler';
3+
4+
export const setupLoggers = (debug: boolean) => {
5+
const warn = console.warn;
6+
console.warn = (...logs: any[]) => warn('\x1b[33m', ...logs, '\x1b[0m');
7+
const error = console.error;
8+
console.error = (...logs: any[]) => error('\x1b[31m', ...logs, '\x1b[0m');
9+
if (!debug) {
10+
console.log = console.debug = (...logs: any[]) => void 0;
11+
} else {
12+
console.warn('Debug mode is on. You can see logs now.');
13+
}
14+
};
15+
16+
export const loadQueueConfigs = (filepath: string) => {
17+
if (!fs.existsSync(filepath)) throw new Error('Config file could not be found. Please make sure the file exists.');
18+
19+
const rawConfig = JSON.parse(fs.readFileSync(filepath, 'utf-8')) as {[host: string]: QueueConfig[]};
20+
if (!rawConfig || typeof rawConfig !== 'object' || Array.isArray(rawConfig)) {
21+
throw new Error('Invalid config format. Please provide a valid config.');
22+
}
23+
24+
for (const host in rawConfig) {
25+
if (host.includes('/')) {
26+
throw new Error(`Invalid config format. Hostname cannot have '/' in it but found ${JSON.stringify(host)}.`)
27+
}
28+
const configs = rawConfig[host];
29+
if (!Array.isArray(configs)) {
30+
throw new Error(`Invalid config format. Expected an array for host ${JSON.stringify(host)} but found ${typeof configs}.`);
31+
}
32+
for (const config of configs) {
33+
if (!config.name || typeof config.name !== 'string') {
34+
throw new Error(`Invalid config format. Expected a valid string for queue name in host ${JSON.stringify(host)} but found ${typeof config.name}.`);
35+
}
36+
if (config.url && typeof config.url !== 'string') {
37+
throw new Error(`Invalid config format. Expected nothing or a valid string for queue url in host ${JSON.stringify(host)} but found ${typeof config.url}.`);
38+
}
39+
}
40+
}
41+
return rawConfig;
42+
}

‎tslint.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@
66
"jsRules": {},
77
"rules": {
88
"no-console": false,
9-
"radix": false
9+
"radix": false,
10+
"forin": false
1011
},
1112
"rulesDirectory": []
1213
}

0 commit comments

Comments
 (0)
Please sign in to comment.