diff --git a/lib/actions/app.coffee b/lib/actions/app.coffee index ab732ab8..8ef8a07f 100644 --- a/lib/actions/app.coffee +++ b/lib/actions/app.coffee @@ -1,4 +1,4 @@ -_ = require('lodash') +_ = require('lodash-contrib') async = require('async') resin = require('resin-sdk') ui = require('../ui') @@ -29,9 +29,7 @@ exports.create = permissions.user (params, options) -> ], errors.handle exports.list = permissions.user -> - resin.models.application.getAll (error, applications) -> - errors.handle(error) if error? - + resin.models.application.getAll errors.handleCallback (applications) -> log.out ui.widgets.table.horizontal applications, [ 'ID' 'Name' @@ -41,9 +39,7 @@ exports.list = permissions.user -> ] exports.info = permissions.user (params) -> - resin.models.application.get params.id, (error, application) -> - errors.handle(error) if error? - + resin.models.application.get params.id, errors.handleCallback (application) -> log.out ui.widgets.table.vertical application, [ 'ID' 'Name' @@ -53,8 +49,7 @@ exports.info = permissions.user (params) -> ] exports.restart = permissions.user (params) -> - resin.models.application.restart params.id, (error) -> - errors.handle(error) if error? + resin.models.application.restart(params.id, _.unary(errors.handle)) exports.remove = permissions.user (params, options) -> ui.patterns.remove 'application', options.yes, (callback) -> @@ -82,5 +77,4 @@ exports.init = permissions.user (params) -> (application, callback) -> resin.vcs.initProjectWithApplication(application, currentDirectory, callback) - ], (error) -> - errors.handle(error) if error? + ], errors.handle diff --git a/lib/actions/auth.coffee b/lib/actions/auth.coffee index 90a380c0..975d117b 100644 --- a/lib/actions/auth.coffee +++ b/lib/actions/auth.coffee @@ -1,4 +1,4 @@ -_ = require('lodash') +_ = require('lodash-contrib') url = require('url') async = require('async') resin = require('resin-sdk') @@ -23,8 +23,7 @@ exports.login = (params) -> ], errors.handle exports.logout = permissions.user -> - resin.auth.logout (error) -> - errors.handle(error) if error? + resin.auth.logout(_.unary(errors.handle)) exports.signup = -> async.waterfall([ @@ -43,8 +42,7 @@ exports.signup = -> ], errors.handle) exports.whoami = permissions.user -> - resin.auth.whoami (error, username) -> - errors.handle(error) if error? + resin.auth.whoami errors.handleCallback (username) -> if not username? error = new Error('Username not found') diff --git a/lib/actions/device.coffee b/lib/actions/device.coffee index 862a1285..b35a26f7 100644 --- a/lib/actions/device.coffee +++ b/lib/actions/device.coffee @@ -7,9 +7,7 @@ errors = require('../errors/errors') permissions = require('../permissions/permissions') exports.list = permissions.user (params, options) -> - resin.models.device.getAllByApplication options.application, (error, devices) -> - errors.handle(error) if error? - + resin.models.device.getAllByApplication options.application, errors.handleCallback (devices) -> log.out ui.widgets.table.horizontal devices, [ 'ID' 'Name' @@ -21,9 +19,7 @@ exports.list = permissions.user (params, options) -> ] exports.info = permissions.user (params) -> - resin.models.device.get params.id, (error, device) -> - errors.handle(error) if error? - + resin.models.device.get params.id, errors.handleCallback (device) -> log.out ui.widgets.table.vertical device, [ 'ID' 'Name' @@ -46,8 +42,7 @@ exports.remove = permissions.user (params, options) -> , errors.handle exports.identify = permissions.user (params) -> - resin.models.device.identify params.uuid, (error) -> - errors.handle(error) if error? + resin.models.device.identify(params.uuid, _.unary(errors.handle)) exports.rename = permissions.user (params) -> async.waterfall [ diff --git a/lib/actions/environment-variables.coffee b/lib/actions/environment-variables.coffee index 18c022be..3cdd2650 100644 --- a/lib/actions/environment-variables.coffee +++ b/lib/actions/environment-variables.coffee @@ -1,4 +1,4 @@ -_ = require('lodash') +_ = require('lodash-contrib') resin = require('resin-sdk') ui = require('../ui') permissions = require('../permissions/permissions') @@ -6,9 +6,7 @@ log = require('../log/log') errors = require('../errors/errors') exports.list = permissions.user (params, options) -> - resin.models.environmentVariables.getAllByApplication options.application, (error, environmentVariables) -> - errors.handle(error) if error? - + resin.models.environmentVariables.getAllByApplication options.application, errors.handleCallback (environmentVariables) -> if not options.verbose environmentVariables = _.reject(environmentVariables, resin.models.environmentVariables.isSystemVariable) @@ -28,9 +26,7 @@ exports.add = permissions.user (params, options) -> else log.info("Warning: using #{params.key}=#{params.value} from host environment") - resin.models.environmentVariables.create options.application, params.key, params.value, (error) -> - errors.handle(error) if error? + resin.models.environmentVariables.create(options.application, params.key, params.value, _.unary(errors.handle)) exports.rename = permissions.user (params, options) -> - resin.models.environmentVariables.update params.id, params.value, (error) -> - errors.handle(error) if error? + resin.models.environmentVariables.update(params.id, params.value, _.unary(errors.handle)) diff --git a/lib/actions/keys.coffee b/lib/actions/keys.coffee index 57d20ab7..112e71f9 100644 --- a/lib/actions/keys.coffee +++ b/lib/actions/keys.coffee @@ -10,15 +10,11 @@ permissions = require('../permissions/permissions') errors = require('../errors/errors') exports.list = permissions.user -> - resin.models.key.getAll (error, keys) -> - errors.handle(error) if error? - + resin.models.key.getAll errors.handleCallback (keys) -> log.out ui.widgets.table.horizontal keys, [ 'ID', 'Title' ] exports.info = permissions.user (params) -> - resin.models.key.get params.id, (error, key) -> - errors.handle(error) if error? - + resin.models.key.get params.id, errors.handleCallback (key) -> key.public_key = '\n' + _.str.chop(key.public_key, resin.settings.get('sshKeyWidth')).join('\n') log.out(ui.widgets.table.vertical(key, [ 'ID', 'Title', 'Public Key' ])) diff --git a/lib/actions/logs.coffee b/lib/actions/logs.coffee index a666bd49..b783185a 100644 --- a/lib/actions/logs.coffee +++ b/lib/actions/logs.coffee @@ -10,6 +10,5 @@ exports.logs = permissions.user (params, options) -> resin.logs.subscribe params.uuid, { history: options.num or LOGS_HISTORY_COUNT tail: options.tail - }, (error, message) -> - errors.handle(error) if error? + }, errors.handleCallback (message) -> log.array(message, log.out) diff --git a/lib/actions/os.coffee b/lib/actions/os.coffee index bb87d776..97b916fc 100644 --- a/lib/actions/os.coffee +++ b/lib/actions/os.coffee @@ -54,6 +54,5 @@ exports.download = (params, options) -> bar.tick(state.received - received) received = state.received - ], (error) -> - errors.handle(error) if error? + ], errors.handleCallback -> log.info("\nFinished downloading #{outputFile}") diff --git a/lib/errors/errors.coffee b/lib/errors/errors.coffee index 6fea65cf..6837af68 100644 --- a/lib/errors/errors.coffee +++ b/lib/errors/errors.coffee @@ -22,3 +22,11 @@ exports.handle = (error, exit = true) -> errorCode = 1 process.exit(errorCode) if exit + +exports.handleCallback = (callback, context, exit) -> + if not _.isFunction(callback) + throw new Error('Callback is not a function') + + return (error, args...) -> + exports.handle(error, exit) if error? + return callback.apply(context, args) diff --git a/lib/errors/errors.spec.coffee b/lib/errors/errors.spec.coffee index a9706ee3..497fc8d0 100644 --- a/lib/errors/errors.spec.coffee +++ b/lib/errors/errors.spec.coffee @@ -1,3 +1,4 @@ +_ = require('lodash') expect = require('chai').expect sinon = require('sinon') log = require('../log/log') @@ -77,3 +78,52 @@ describe 'Errors:', -> checkProcessExitOption error, false, (processExitStub, logErrorStub) -> expect(logErrorStub).to.have.been.calledOnce expect(logErrorStub).to.have.been.calledWith('No such file or directory: hello') + + describe '#handleCallback()', -> + + it 'should throw an error if callback is not a function', -> + expect -> + errors.handleCallback('hello') + .to.throw('Callback is not a function') + + it 'should return a new function', -> + callback = errors.handleCallback(_.noop) + expect(callback).to.be.an.instanceof(Function) + + describe 'given no error', -> + + it 'should pass arguments back to the callback', -> + spy = sinon.spy() + callback = errors.handleCallback(spy) + callback.call(null, null, 'Hello World', 123) + expect(spy).to.have.been.calledOnce + expect(spy).to.have.been.calledWithExactly('Hello World', 123) + + it 'should be able to pass a context', -> + spy = sinon.spy() + context = + foo: 'bar' + callback = errors.handleCallback(spy, context) + callback.call(null, null, 'Hello World', 123) + expect(spy).to.have.been.calledOn(context) + + describe 'given an error', -> + + beforeEach -> + @handleStub = sinon.stub(errors, 'handle') + @error = new Error('hello') + + afterEach -> + @handleStub.restore() + + it 'should call handle() with the error', -> + callback = errors.handleCallback(_.noop) + callback.call(null, @error) + expect(@handleStub).to.have.been.calledOnce + expect(@handleStub).to.have.been.calledWith(@error) + + it 'should call handle() with the exit boolean parameter', -> + callback = errors.handleCallback(_.noop, null, false) + callback.call(null, @error) + expect(@handleStub).to.have.been.calledOnce + expect(@handleStub).to.have.been.calledWithExactly(@error, false)