Code cleanup: Use EnigError's vs standard Error. WIP...

This commit is contained in:
Bryan Ashby 2018-12-02 19:33:07 -07:00
parent 8f9f4227c1
commit 0c23339a2d
10 changed files with 88 additions and 77 deletions

View File

@ -7,6 +7,7 @@ const Door = require('./door.js');
const theme = require('./theme.js'); const theme = require('./theme.js');
const ansi = require('./ansi_term.js'); const ansi = require('./ansi_term.js');
const Events = require('./events.js'); const Events = require('./events.js');
const { Errors } = require('./enig_error.js');
const async = require('async'); const async = require('async');
const assert = require('assert'); const assert = require('assert');
@ -98,7 +99,7 @@ exports.getModule = class AbracadabraModule extends MenuModule {
if(_.isString(self.config.tooManyArt)) { if(_.isString(self.config.tooManyArt)) {
theme.displayThemeArt( { client : self.client, name : self.config.tooManyArt }, function displayed() { theme.displayThemeArt( { client : self.client, name : self.config.tooManyArt }, function displayed() {
self.pausePrompt( () => { self.pausePrompt( () => {
callback(new Error('Too many active instances')); return callback(Errors.AccessDenied('Too many active instances'));
}); });
}); });
} else { } else {
@ -106,7 +107,7 @@ exports.getModule = class AbracadabraModule extends MenuModule {
// :TODO: Use MenuModule.pausePrompt() // :TODO: Use MenuModule.pausePrompt()
self.pausePrompt( () => { self.pausePrompt( () => {
callback(new Error('Too many active instances')); return callback(Errors.AccessDenied('Too many active instances'));
}); });
} }
} else { } else {

View File

@ -2,11 +2,12 @@
'use strict'; 'use strict';
// ENiGMA½ // ENiGMA½
const Config = require('./config.js').get; const Config = require('./config.js').get;
const miscUtil = require('./misc_util.js'); const miscUtil = require('./misc_util.js');
const ansi = require('./ansi_term.js'); const ansi = require('./ansi_term.js');
const aep = require('./ansi_escape_parser.js'); const aep = require('./ansi_escape_parser.js');
const sauce = require('./sauce.js'); const sauce = require('./sauce.js');
const { Errors } = require('./enig_error.js');
// deps // deps
const fs = require('graceful-fs'); const fs = require('graceful-fs');
@ -209,7 +210,7 @@ function getArt(name, options, cb) {
return getArtFromPath(readPath, options, cb); return getArtFromPath(readPath, options, cb);
} }
return cb(new Error(`No matching art for supplied criteria: ${name}`)); return cb(Errors.DoesNotExist(`No matching art for supplied criteria: ${name}`));
}); });
} }
@ -236,7 +237,7 @@ function display(client, art, options, cb) {
} }
if(!art || !art.length) { if(!art || !art.length) {
return cb(new Error('Empty art')); return cb(Errors.Invalid('No art supplied!'));
} }
options.mciReplaceChar = options.mciReplaceChar || ' '; options.mciReplaceChar = options.mciReplaceChar || ' ';

View File

@ -1,11 +1,12 @@
/* jslint node: true */ /* jslint node: true */
'use strict'; 'use strict';
const MenuModule = require('./menu_module.js').MenuModule; const { MenuModule } = require('./menu_module.js');
const resetScreen = require('./ansi_term.js').resetScreen; const { resetScreen } = require('./ansi_term.js');
const { Errors } = require('./enig_error.js');
// deps
const async = require('async'); const async = require('async');
const _ = require('lodash');
const http = require('http'); const http = require('http');
const net = require('net'); const net = require('net');
const crypto = require('crypto'); const crypto = require('crypto');
@ -60,15 +61,17 @@ exports.getModule = class BBSLinkModule extends MenuModule {
async.series( async.series(
[ [
function validateConfig(callback) { function validateConfig(callback) {
if(_.isString(self.config.sysCode) && return self.validateConfigFields(
_.isString(self.config.authCode) && {
_.isString(self.config.schemeCode) && host : 'string',
_.isString(self.config.door)) sysCode : 'string',
{ authCode : 'string',
callback(null); schemeCode : 'string',
} else { door : 'string',
callback(new Error('Configuration is missing option(s)')); port : 'number',
} },
callback
);
}, },
function acquireToken(callback) { function acquireToken(callback) {
// //
@ -112,10 +115,9 @@ exports.getModule = class BBSLinkModule extends MenuModule {
var status = body.trim(); var status = body.trim();
if('complete' === status) { if('complete' === status) {
callback(null); return callback(null);
} else {
callback(new Error('Bad authentication status: ' + status));
} }
return callback(Errors.AccessDenied(`Bad authentication status: ${status}`));
}); });
}, },
function createTelnetBridge(callback) { function createTelnetBridge(callback) {
@ -158,7 +160,7 @@ exports.getModule = class BBSLinkModule extends MenuModule {
bridgeConnection.on('end', function connectionEnd() { bridgeConnection.on('end', function connectionEnd() {
restorePipe(); restorePipe();
callback(clientTerminated ? new Error('Client connection terminated') : null); return callback(clientTerminated ? Errors.General('Client connection terminated') : null);
}); });
bridgeConnection.on('error', function error(err) { bridgeConnection.on('error', function error(err) {

View File

@ -2,12 +2,12 @@
'use strict'; 'use strict';
// enigma-bbs // enigma-bbs
const MenuModule = require('../core/menu_module.js').MenuModule; const { MenuModule } = require('../core/menu_module.js');
const resetScreen = require('../core/ansi_term.js').resetScreen; const { resetScreen } = require('../core/ansi_term.js');
const { Errors } = require('./enig_error.js');
// deps // deps
const async = require('async'); const async = require('async');
const _ = require('lodash');
const RLogin = require('rlogin'); const RLogin = require('rlogin');
exports.moduleInfo = { exports.moduleInfo = {
@ -32,13 +32,15 @@ exports.getModule = class CombatNetModule extends MenuModule {
async.series( async.series(
[ [
function validateConfig(callback) { function validateConfig(callback) {
if(!_.isString(self.config.password)) { return self.validateConfigFields(
return callback(new Error('Config requires "password"!')); {
} host : 'string',
if(!_.isString(self.config.bbsTag)) { password : 'string',
return callback(new Error('Config requires "bbsTag"!')); bbsTag : 'string',
} rloginPort : 'number',
return callback(null); },
callback
);
}, },
function establishRloginConnection(callback) { function establishRloginConnection(callback) {
self.client.term.write(resetScreen()); self.client.term.write(resetScreen());
@ -51,12 +53,13 @@ exports.getModule = class CombatNetModule extends MenuModule {
}; };
const rlogin = new RLogin( const rlogin = new RLogin(
{ 'clientUsername' : self.config.password, {
'serverUsername' : `${self.config.bbsTag}${self.client.user.username}`, clientUsername : self.config.password,
'host' : self.config.host, serverUsername : `${self.config.bbsTag}${self.client.user.username}`,
'port' : self.config.rloginPort, host : self.config.host,
'terminalType' : self.client.term.termClient, port : self.config.rloginPort,
'terminalSpeed' : 57600 terminalType : self.client.term.termClient,
terminalSpeed : 57600
} }
); );
@ -88,7 +91,7 @@ exports.getModule = class CombatNetModule extends MenuModule {
self.client.term.output.on('data', sendToRloginBuffer); self.client.term.output.on('data', sendToRloginBuffer);
} else { } else {
return callback(new Error('Failed to establish establish CombatNet connection')); return callback(Errors.General('Failed to establish establish CombatNet connection'));
} }
} }
); );

View File

@ -2,8 +2,9 @@
'use strict'; 'use strict';
// ENiGMA½ // ENiGMA½
const ansi = require('./ansi_term.js'); const ansi = require('./ansi_term.js');
const Events = require('./events.js'); const Events = require('./events.js');
const { Errors } = require('./enig_error.js');
// deps // deps
const async = require('async'); const async = require('async');
@ -15,7 +16,7 @@ function ansiDiscoverHomePosition(client, cb) {
// We want to find the home position. ANSI-BBS and most terminals // We want to find the home position. ANSI-BBS and most terminals
// utilize 1,1 as home. However, some terminals such as ConnectBot // utilize 1,1 as home. However, some terminals such as ConnectBot
// think of home as 0,0. If this is the case, we need to offset // think of home as 0,0. If this is the case, we need to offset
// our positioning to accomodate for such. // our positioning to accommodate for such.
// //
const done = function(err) { const done = function(err) {
client.removeListener('cursor position report', cprListener); client.removeListener('cursor position report', cprListener);
@ -32,7 +33,7 @@ function ansiDiscoverHomePosition(client, cb) {
// //
if(h > 1 || w > 1) { if(h > 1 || w > 1) {
client.log.warn( { height : h, width : w }, 'Ignoring ANSI home position CPR due to unexpected values'); client.log.warn( { height : h, width : w }, 'Ignoring ANSI home position CPR due to unexpected values');
return done(new Error('Home position CPR expected to be 0,0, or 1,1')); return done(Errors.UnexpectedState('Home position CPR expected to be 0,0, or 1,1'));
} }
if(0 === h & 0 === w) { if(0 === h & 0 === w) {
@ -49,7 +50,7 @@ function ansiDiscoverHomePosition(client, cb) {
client.once('cursor position report', cprListener); client.once('cursor position report', cprListener);
const giveUpTimer = setTimeout( () => { const giveUpTimer = setTimeout( () => {
return done(new Error('Giving up on home position CPR')); return done(Errors.General('Giving up on home position CPR'));
}, 3000); // 3s }, 3000); // 3s
client.term.write(`${ansi.goHome()}${ansi.queryPos()}`); // go home, query pos client.term.write(`${ansi.goHome()}${ansi.queryPos()}`); // go home, query pos
@ -78,14 +79,14 @@ function ansiQueryTermSizeIfNeeded(client, cb) {
const w = pos[1]; const w = pos[1];
// //
// Netrunner for example gives us 1x1 here. Not really useful. Ignore // NetRunner for example gives us 1x1 here. Not really useful. Ignore
// values that seem obviously bad. // values that seem obviously bad.
// //
if(h < 10 || w < 10) { if(h < 10 || w < 10) {
client.log.warn( client.log.warn(
{ height : h, width : w }, { height : h, width : w },
'Ignoring ANSI CPR screen size query response due to very small values'); 'Ignoring ANSI CPR screen size query response due to very small values');
return done(new Error('Term size <= 10 considered invalid')); return done(Errors.Invalid('Term size <= 10 considered invalid'));
} }
client.term.termHeight = h; client.term.termHeight = h;
@ -107,7 +108,7 @@ function ansiQueryTermSizeIfNeeded(client, cb) {
// give up after 2s // give up after 2s
const giveUpTimer = setTimeout( () => { const giveUpTimer = setTimeout( () => {
return done(new Error('No term size established by CPR within timeout')); return done(Errors.General('No term size established by CPR within timeout'));
}, 2000); }, 2000);
// Start the process: Query for CPR // Start the process: Query for CPR
@ -116,8 +117,6 @@ function ansiQueryTermSizeIfNeeded(client, cb) {
function prepareTerminal(term) { function prepareTerminal(term) {
term.rawWrite(ansi.normal()); term.rawWrite(ansi.normal());
//term.rawWrite(ansi.disableVT100LineWrapping());
// :TODO: set xterm stuff -- see x84/others
} }
function displayBanner(term) { function displayBanner(term) {

View File

@ -2,12 +2,12 @@
'use strict'; 'use strict';
// enigma-bbs // enigma-bbs
const MenuModule = require('../core/menu_module.js').MenuModule; const { MenuModule } = require('./menu_module.js');
const resetScreen = require('../core/ansi_term.js').resetScreen; const { resetScreen } = require('./ansi_term.js');
const { Errors } = require('./enig_error.js');
// deps // deps
const async = require('async'); const async = require('async');
const _ = require('lodash');
const SSHClient = require('ssh2').Client; const SSHClient = require('ssh2').Client;
exports.moduleInfo = { exports.moduleInfo = {
@ -34,16 +34,17 @@ exports.getModule = class DoorPartyModule extends MenuModule {
async.series( async.series(
[ [
function validateConfig(callback) { function validateConfig(callback) {
if(!_.isString(self.config.username)) { return self.validateConfigFields(
return callback(new Error('Config requires "username"!')); {
} host : 'string',
if(!_.isString(self.config.password)) { username : 'string',
return callback(new Error('Config requires "password"!')); password : 'string',
} bbsTag : 'string',
if(!_.isString(self.config.bbsTag)) { sshPort : 'number',
return callback(new Error('Config requires "bbsTag"!')); rloginPort : 'number',
} },
return callback(null); callback
);
}, },
function establishSecureConnection(callback) { function establishSecureConnection(callback) {
self.client.term.write(resetScreen()); self.client.term.write(resetScreen());
@ -71,7 +72,7 @@ exports.getModule = class DoorPartyModule extends MenuModule {
// establish tunnel for rlogin // establish tunnel for rlogin
sshClient.forwardOut('127.0.0.1', self.config.sshPort, self.config.host, self.config.rloginPort, (err, stream) => { sshClient.forwardOut('127.0.0.1', self.config.sshPort, self.config.host, self.config.rloginPort, (err, stream) => {
if(err) { if(err) {
return callback(new Error('Failed to establish tunnel')); return callback(Errors.General('Failed to establish tunnel'));
} }
// //

View File

@ -162,7 +162,7 @@ class ScheduledEvent {
{ eventName : this.name, action : this.action, exitCode : exitCode }, { eventName : this.name, action : this.action, exitCode : exitCode },
'Bad exit code while performing scheduled event action'); 'Bad exit code while performing scheduled event action');
} }
return cb(exitCode ? new Error(`Bad exit code while performing scheduled event action: ${exitCode}`) : null); return cb(exitCode ? Errors.ExternalProcess(`Bad exit code while performing scheduled event action: ${exitCode}`) : null);
}); });
} }
} }

View File

@ -1,7 +1,9 @@
/* jslint node: true */ /* jslint node: true */
'use strict'; 'use strict';
let _ = require('lodash'); const { Errors } = require('./enig_error.js');
const _ = require('lodash');
// FNV-1a based on work here: https://github.com/wiedi/node-fnv // FNV-1a based on work here: https://github.com/wiedi/node-fnv
module.exports = class FNV1a { module.exports = class FNV1a {
@ -23,7 +25,7 @@ module.exports = class FNV1a {
} }
if(!Buffer.isBuffer(data)) { if(!Buffer.isBuffer(data)) {
throw new Error('data must be String or Buffer!'); throw Errors.Invalid('data must be String or Buffer!');
} }
for(let b of data) { for(let b of data) {

View File

@ -3,6 +3,7 @@
// ENiGMA½ // ENiGMA½
const logger = require('./logger.js'); const logger = require('./logger.js');
const { ErrorReasons } = require('./enig_error.js');
// deps // deps
const async = require('async'); const async = require('async');
@ -30,9 +31,8 @@ function startListening(cb) {
async.each( [ 'login', 'content' ], (category, next) => { async.each( [ 'login', 'content' ], (category, next) => {
moduleUtil.loadModulesForCategory(`${category}Servers`, (err, module) => { moduleUtil.loadModulesForCategory(`${category}Servers`, (err, module) => {
// :TODO: use enig error here!
if(err) { if(err) {
if('EENIGMODDISABLED' === err.code) { if(ErrorReasons.Disabled === err.reasonCode) {
logger.log.debug(err.message); logger.log.debug(err.message);
} else { } else {
logger.log.info( { err : err }, 'Failed loading module'); logger.log.info( { err : err }, 'Failed loading module');

View File

@ -4,6 +4,10 @@
// ENiGMA½ // ENiGMA½
const Config = require('./config.js').get; const Config = require('./config.js').get;
const Log = require('./logger.js').log; const Log = require('./logger.js').log;
const {
Errors,
ErrorReasons
} = require('./enig_error.js');
// deps // deps
const fs = require('graceful-fs'); const fs = require('graceful-fs');
@ -28,9 +32,7 @@ function loadModuleEx(options, cb) {
const modConfig = _.isObject(Config[options.category]) ? Config[options.category][options.name] : null; const modConfig = _.isObject(Config[options.category]) ? Config[options.category][options.name] : null;
if(_.isObject(modConfig) && false === modConfig.enabled) { if(_.isObject(modConfig) && false === modConfig.enabled) {
const err = new Error(`Module "${options.name}" is disabled`); return cb(Errors.AccessDenied(`Module "${options.name}" is disabled`, ErrorReasons.Disabled));
err.code = 'EENIGMODDISABLED';
return cb(err);
} }
// //
@ -56,11 +58,11 @@ function loadModuleEx(options, cb) {
} }
if(!_.isObject(mod.moduleInfo)) { if(!_.isObject(mod.moduleInfo)) {
return cb(new Error('Module is missing "moduleInfo" section')); return cb(Errors.Invalid(`No exported "moduleInfo" block for module ${modPath}!`));
} }
if(!_.isFunction(mod.getModule)) { if(!_.isFunction(mod.getModule)) {
return cb(new Error('Invalid or missing "getModule" method for module!')); return cb(Errors.Invalid(`No exported "getModule" method for module ${modPath}!`));
} }
return cb(null, mod); return cb(null, mod);
@ -70,7 +72,7 @@ function loadModule(name, category, cb) {
const path = Config().paths[category]; const path = Config().paths[category];
if(!_.isString(path)) { if(!_.isString(path)) {
return cb(new Error(`Not sure where to look for "${name}" of category "${category}"`)); return cb(Errors.DoesNotExist(`Not sure where to look for module "${name}" of category "${category}"`));
} }
loadModuleEx( { name : name, path : path, category : category }, function loaded(err, mod) { loadModuleEx( { name : name, path : path, category : category }, function loaded(err, mod) {