diff --git a/migrations/20160208164735-groups-add-admin.js b/migrations/20160208164735-groups-add-admin.js index 83b4d2359..d2dc24812 100644 --- a/migrations/20160208164735-groups-add-admin.js +++ b/migrations/20160208164735-groups-add-admin.js @@ -12,8 +12,6 @@ exports.up = function(db, callback) { db.all('SELECT * FROM users WHERE admin=1', function (error, results) { if (error) return done(error); - console.dir(results); - async.eachSeries(results, function (r, next) { db.runSql('INSERT INTO groupMembers (groupId, userId) VALUES (?, ?)', [ ADMIN_GROUP_ID, r.id ], next); }, done); diff --git a/src/apphealthmonitor.js b/src/apphealthmonitor.js index 01672a13e..17804f242 100644 --- a/src/apphealthmonitor.js +++ b/src/apphealthmonitor.js @@ -181,12 +181,10 @@ function processApp(callback) { if (error) return callback(error); async.each(allApps, checkAppHealth, function (error) { - if (error) console.error(error); - const alive = allApps .filter(function (a) { return a.installationState === apps.ISTATE_INSTALLED && a.runState === apps.RSTATE_RUNNING && a.health === apps.HEALTH_HEALTHY; }); - debug(`app health: ${alive.length} alive / ${allApps.length - alive.length} dead`); + debug(`app health: ${alive.length} alive / ${allApps.length - alive.length} dead.` + (error ? ` ${error.reason}` : '')); callback(null); }); @@ -201,7 +199,7 @@ function run(intervalSecs, callback) { processApp, // this is first because docker.getEvents seems to get 'stuck' sometimes processDockerEvents.bind(null, intervalSecs) ], function (error) { - if (error) debug(error); + if (error) debug(`run: could not check app health. ${error.message}`); callback(); }); diff --git a/src/appstore.js b/src/appstore.js index fa2cef44c..439de3247 100644 --- a/src/appstore.js +++ b/src/appstore.js @@ -539,7 +539,7 @@ function createTicket(info, auditSource, callback) { if (error) return callback(error); collectAppInfoIfNeeded(function (error, result) { - if (error) console.error('Unable to get app info', error); + if (error) return callback(error); if (result) info.app = result; let url = settings.apiServerOrigin() + '/api/v1/ticket'; diff --git a/src/database.js b/src/database.js index 4fb9279bf..15df7e49d 100644 --- a/src/database.js +++ b/src/database.js @@ -80,7 +80,7 @@ function reconnect(callback) { gConnectionPool.getConnection(function (error, connection) { if (error) { - debug('reconnect: unable to reestablish connection to database. Try again in 10 seconds.', error.message); + debug(`reconnect: db connection error. ${error.message} fatal:${error.fatal} code:${error.code}. Will retry in 10 seconds`); return setTimeout(reconnect.bind(null, callback), 10000); } @@ -89,7 +89,7 @@ function reconnect(callback) { // this function should be invoked only when we have no callbacks pending and we have a fatal error assert(error.fatal, 'Non-fatal error on connection object'); - debug('reconnect: unhandled mysql connection error. Will reconnect in 10 seconds', error); + debug(`reconnect: db connection error. ${error.message} fatal:${error.fatal} code:${error.code}. Will retry in 10 seconds`); gDefaultConnection = null; diff --git a/src/routes/cloudron.js b/src/routes/cloudron.js index 0c9a4ab65..b498b468a 100644 --- a/src/routes/cloudron.js +++ b/src/routes/cloudron.js @@ -87,7 +87,7 @@ function passwordResetRequest(req, res, next) { if (!req.body.identifier || typeof req.body.identifier !== 'string') return next(new HttpError(401, 'A identifier must be non-empty string')); users.resetPasswordByIdentifier(req.body.identifier, function (error) { - if (error && error.reason !== BoxError.NOT_FOUND) console.error(error); + if (error && error.reason !== BoxError.NOT_FOUND) return next(BoxError.toHttpError(error)); next(new HttpSuccess(202, {})); }); @@ -108,10 +108,10 @@ function passwordReset(req, res, next) { // setPassword clears the resetToken users.setPassword(userObject, req.body.password, function (error) { if (error && error.reason === BoxError.BAD_FIELD) return next(new HttpError(400, error.message)); - if (error) return next(new HttpError(500, error)); + if (error) return next(BoxError.toHttpError(error)); tokens.add(tokens.ID_WEBADMIN, userObject.id, Date.now() + constants.DEFAULT_TOKEN_EXPIRATION, {}, function (error, result) { - if (error) return next(new HttpError(500, error)); + if (error) return next(BoxError.toHttpError(error)); next(new HttpSuccess(202, { accessToken: result.accessToken })); }); diff --git a/src/scheduler.js b/src/scheduler.js index 16e12f5e3..b38e778da 100644 --- a/src/scheduler.js +++ b/src/scheduler.js @@ -13,27 +13,21 @@ let apps = require('./apps.js'), docker = require('./docker.js'), _ = require('underscore'); -var NOOP_CALLBACK = function (error) { if (error) debug('Unhandled error: ', error); }; - // appId -> { schedulerConfig (manifest), cronjobs } var gState = { }; -function sync(callback) { - assert(!callback || typeof callback === 'function'); - - callback = callback || NOOP_CALLBACK; - +function sync() { apps.getAll(function (error, allApps) { - if (error) return callback(error); + if (error) return debug(`sync: error getting app list. ${error.message}`); var allAppIds = allApps.map(function (app) { return app.id; }); var removedAppIds = _.difference(Object.keys(gState), allAppIds); - if (removedAppIds.length !== 0) debug('sync: stopping jobs of removed apps %j', removedAppIds); + if (removedAppIds.length !== 0) debug(`sync: stopping jobs of removed apps ${JSON.stringify(removedAppIds)}`); async.eachSeries(removedAppIds, function (appId, iteratorDone) { stopJobs(appId, gState[appId], iteratorDone); }, function (error) { - if (error) debug('sync: error stopping jobs of removed apps', error); + if (error) debug(`sync: error stopping jobs of removed apps: ${error.message}`); gState = _.omit(gState, removedAppIds); @@ -48,7 +42,7 @@ function sync(callback) { } stopJobs(app.id, appState, function (error) { - if (error) debug(`sync: error stopping jobs of ${app.fqdn} : ${error.message}`); + if (error) debug(`sync: error stopping jobs of ${app.id} : ${error.message}`); if (!schedulerConfig) { delete gState[app.id]; @@ -75,7 +69,7 @@ function killContainer(containerName, callback) { docker.stopContainerByName.bind(null, containerName), docker.deleteContainerByName.bind(null, containerName) ], function (error) { - if (error) debug('Failed to kill task with name %s : %s', containerName, error.message); + if (error) debug(`killContainer: failed to kill task with name ${containerName} : ${error.message}`); callback(error); }); @@ -101,6 +95,7 @@ function createCronJobs(app, schedulerConfig) { assert.strictEqual(typeof app, 'object'); assert(schedulerConfig && typeof schedulerConfig === 'object'); + const appId = app.id; var jobs = { }; Object.keys(schedulerConfig).forEach(function (taskName) { @@ -112,7 +107,9 @@ function createCronJobs(app, schedulerConfig) { var cronJob = new CronJob({ cronTime: cronTime, // at this point, the pattern has been validated - onTick: runTask.bind(null, app.id, taskName), // put the app id in closure, so we don't use the outdated app object by mistake + onTick: () => runTask(appId, taskName, (error) => { // put the app id in closure, so we don't use the outdated app object by mistake + if (error) debug(`could not run task ${taskName} : ${error.message}`); + }), start: true }); @@ -125,12 +122,10 @@ function createCronJobs(app, schedulerConfig) { function runTask(appId, taskName, callback) { assert.strictEqual(typeof appId, 'string'); assert.strictEqual(typeof taskName, 'string'); - assert(!callback || typeof callback === 'function'); + assert.strictEqual(typeof callback, 'function'); const JOB_MAX_TIME = 30 * 60 * 1000; // 30 minutes - callback = callback || NOOP_CALLBACK; - apps.get(appId, function (error, app) { if (error) return callback(error);