From 6ee4b9e420702b52d6584c4d8b6db97f99d80132 Mon Sep 17 00:00:00 2001 From: "Eslam A. Hefnawy" Date: Thu, 30 Jun 2016 13:25:57 +0200 Subject: [PATCH 1/3] more validation and better error messages --- lib/classes/Error.js | 19 ++++++- lib/classes/PluginManager.js | 6 +- lib/classes/Service.js | 56 +++++++++++++++---- .../compile/events/apiGateway/lib/methods.js | 7 ++- .../events/apiGateway/lib/permissions.js | 7 ++- .../events/apiGateway/lib/resources.js | 7 ++- .../compile/events/apiGateway/lib/validate.js | 29 ++++++++-- .../aws/deploy/compile/events/s3/index.js | 14 ++++- .../deploy/compile/events/schedule/index.js | 14 ++++- .../aws/deploy/compile/functions/index.js | 19 ++++--- lib/plugins/aws/deploy/lib/deployFunctions.js | 7 ++- lib/plugins/aws/deploy/lib/validate.js | 8 +-- lib/plugins/aws/deploy/tests/validate.js | 5 -- lib/plugins/aws/invoke/index.js | 2 +- lib/plugins/create/create.js | 6 +- tests/classes/Service.js | 39 +++++++++++++ 16 files changed, 199 insertions(+), 46 deletions(-) diff --git a/lib/classes/Error.js b/lib/classes/Error.js index bae4edff7..78c18a12d 100644 --- a/lib/classes/Error.js +++ b/lib/classes/Error.js @@ -21,9 +21,26 @@ module.exports.logError = (e) => { line = `${line}-`; } + consoleLog(' '); consoleLog(chalk.yellow(` ${errorType} ${line}`)); consoleLog(' '); - consoleLog(chalk.yellow(` ${e.message}`)); + + // for + const words = e.message.split(' '); + let logLine = []; + words.forEach(word => { + logLine.push(word); + const logLineString = logLine.join(' '); + if (logLineString.length > 50) { + consoleLog(chalk.yellow(` ${logLineString}`)); + logLine = []; + } + }); + + if (logLine.length != 0) { + consoleLog(chalk.yellow(` ${logLine.join(' ')}`)); + } + consoleLog(' '); if (e.name !== 'ServerlessError') { diff --git a/lib/classes/PluginManager.js b/lib/classes/PluginManager.js index 6638b3608..3e229e7a7 100644 --- a/lib/classes/PluginManager.js +++ b/lib/classes/PluginManager.js @@ -32,7 +32,11 @@ class PluginManager { validateCommands(commandsArray) { // TODO: implement an option to get deeper than one level if (!this.commands[commandsArray[0]]) { - throw new this.serverless.classes.Error(`command "${commandsArray[0]}" not found.`); + const errorMessage = [ + `command "${commandsArray[0]}" not found`, + ` Run "sls help" for a list of all available commands.` + ].join(); + throw new this.serverless.classes.Error(errorMessage); } } diff --git a/lib/classes/Service.js b/lib/classes/Service.js index 77a436ba7..b8ae4ff6e 100644 --- a/lib/classes/Service.js +++ b/lib/classes/Service.js @@ -54,6 +54,15 @@ class Service { throw new SError('"functions" property is missing in serverless.yaml'); } + if (['aws', 'azure', 'google', 'ibm'].indexOf(serverlessYaml.provider)) { + const errorMessage = [ + `Provider "${serverlessYaml.provider}" is not supported.`, + ` Valid values for provider are: aws, azure, google, ibm.`, + ` Please provide one of those values to the "provider" property in serverless.yaml.` + ].join(''); + throw new SError(errorMessage); + } + that.service = serverlessYaml.service; that.provider = serverlessYaml.provider; that.variableSyntax = serverlessYaml.variableSyntax; @@ -167,12 +176,21 @@ class Service { // Populate if (!value && !value !== '') { + const errorMessage = [ + `Variable "${variableName}" doesn't exist in serverless.env.yaml.`, + ` Please add it to serverless.env.yaml.` + ].join(''); throw new that.serverless.classes - .Error(`Variable "${variableName}" doesn't exist in serverless.env.yaml.`); + .Error(errorMessage); } else if (typeof value === 'string') { if (variableString.split('.').length > 1) { + const errorMessage = [ + `Trying to access sub properties of a string variable "${variableName}".`, + ` Please make sure the variable in serverless.env.yaml`, + ` is an object, otherwise you can't use the dot notation for that variable in serverless.yaml` + ].join(''); throw new that.serverless.classes - .Error('Trying to access sub properties of a string variable'); + .Error(errorMessage); } // for string variables, we use replaceall in case the user // includes the variable as a substring (ie. "hello ${name}") @@ -185,8 +203,13 @@ class Service { subProperties.splice(0, 1); subProperties.forEach(subProperty => { if (!value[subProperty]) { + const errorMessage = [ + `Variable "${variableName}" doesn't have sub property "${subProperty}".`, + ` Please make sure the variable is the intended object in serverless.env.yaml,`, + ` or reference the correct sub property in serverless.yaml` + ].join(''); throw new that.serverless.classes - .Error(`Invalid sub property for variable "${variableName}"`); + .Error(errorMessage); } value = value[subProperty]; }); @@ -195,18 +218,31 @@ class Service { val = replaceall(variableSyntax, value, val); } else { if (val !== variableSyntax) { + const errorMessage = [ + `Trying to populate non string variables into a string for variable "${variableName}".`, + ` Please make sure the variable value in serverless.env.yaml is a string` + ].join(''); throw new that.serverless.classes - .Error('Trying to populate non string variables into a string'); + .Error(errorMessage); } val = value; } } else if (variableString.split('.').length > 1) { + const errorMessage = [ + `Trying to access sub properties of a non-object variable "${variableName}"`, + ` Please make sure the variable is an object in serverless.env.yaml,`, + ` otherwise, you can't use the dot notation for that variable in serverless.yaml` + ].join(''); throw new that.serverless.classes - .Error('Trying to access sub properties of a non-object variable'); + .Error(errorMessage); } else { if (val !== variableSyntax) { + const errorMessage = [ + `Trying to populate non string variables into a string for variable "${variableName}".`, + ` Please make sure the variable value in serverless.env.yaml is a string` + ].join(''); throw new that.serverless.classes - .Error('Trying to populate non string variables into a string'); + .Error(errorMessage); } val = value; // not string nor object } @@ -240,14 +276,14 @@ class Service { if (functionName in this.functions) { return this.functions[functionName]; } - throw new SError(`function ${functionName} doesn't exist in this Service`); + throw new SError(`Function "${functionName}" doesn't exist in this Service`); } getEventInFunction(eventName, functionName) { if (eventName in this.getFunction(functionName).events) { return this.getFunction(functionName).events[eventName]; } - throw new SError(`event ${eventName} doesn't exist in function ${functionName}`); + throw new SError(`Event "${eventName}" doesn't exist in function "${functionName}"`); } getAllEventsInFunction(functionName) { @@ -258,7 +294,7 @@ class Service { if (stageName in this.environment.stages) { return this.environment.stages[stageName]; } - throw new SError(`stage ${stageName} doesn't exist in this Service`); + throw new SError(`Stage "${stageName}" doesn't exist in this service.`); } getAllStages() { @@ -269,7 +305,7 @@ class Service { if (regionName in this.getStage(stageName).regions) { return this.getStage(stageName).regions[regionName]; } - throw new SError(`region ${regionName} doesn't exist in stage ${stageName}`); + throw new SError(`Region "${regionName}" doesn't exist in stage "${stageName}"`); } getAllRegionsInStage(stageName) { diff --git a/lib/plugins/aws/deploy/compile/events/apiGateway/lib/methods.js b/lib/plugins/aws/deploy/compile/events/apiGateway/lib/methods.js index 929e8d430..cc769de58 100644 --- a/lib/plugins/aws/deploy/compile/events/apiGateway/lib/methods.js +++ b/lib/plugins/aws/deploy/compile/events/apiGateway/lib/methods.js @@ -18,8 +18,13 @@ module.exports = { method = event.http.split(' ')[0]; path = event.http.split(' ')[1]; } else { + const errorMessage = [ + `HTTP event of function ${functionName} is not an object nor a string.`, + ` The correct syntax is: http: get users/list OR an object with "path" and "method" proeprties.`, + ` Please check the docs for more info.` + ].join(''); throw new this.serverless.classes - .Error(`HTTP event of function ${functionName} is not an object nor a string`); + .Error(errorMessage); } const resourceLogicalId = this.resourceLogicalIds[path]; diff --git a/lib/plugins/aws/deploy/compile/events/apiGateway/lib/permissions.js b/lib/plugins/aws/deploy/compile/events/apiGateway/lib/permissions.js index 3f3fd7cf0..d261b8d45 100644 --- a/lib/plugins/aws/deploy/compile/events/apiGateway/lib/permissions.js +++ b/lib/plugins/aws/deploy/compile/events/apiGateway/lib/permissions.js @@ -18,8 +18,13 @@ module.exports = { method = event.http.split(' ')[0]; path = event.http.split(' ')[1]; } else { + const errorMessage = [ + `HTTP event of function ${functionName} is not an object nor a string.`, + ` The correct syntax is: http: get users/list OR an object with "path" and "method" proeprties.`, + ` Please check the docs for more info.` + ].join(''); throw new this.serverless.classes - .Error(`HTTP event of function ${functionName} is not an object nor a string`); + .Error(errorMessage); } const normalizedMethod = method[0].toUpperCase() + diff --git a/lib/plugins/aws/deploy/compile/events/apiGateway/lib/resources.js b/lib/plugins/aws/deploy/compile/events/apiGateway/lib/resources.js index 504625ea3..ed13d5d8e 100644 --- a/lib/plugins/aws/deploy/compile/events/apiGateway/lib/resources.js +++ b/lib/plugins/aws/deploy/compile/events/apiGateway/lib/resources.js @@ -18,8 +18,13 @@ module.exports = { } else if (typeof event.http === 'string') { path = event.http.split(' ')[1]; } else { + const errorMessage = [ + `HTTP event of function ${functionName} is not an object nor a string.`, + ` The correct syntax is: http: get users/list OR an object with "path" and "method" proeprties.`, + ` Please check the docs for more info.` + ].join(''); throw new this.serverless.classes - .Error(`HTTP event of function ${functionName} is not an object nor a string`); + .Error(errorMessage); } while (path !== '') { diff --git a/lib/plugins/aws/deploy/compile/events/apiGateway/lib/validate.js b/lib/plugins/aws/deploy/compile/events/apiGateway/lib/validate.js index 80fd107b8..71636bdb5 100644 --- a/lib/plugins/aws/deploy/compile/events/apiGateway/lib/validate.js +++ b/lib/plugins/aws/deploy/compile/events/apiGateway/lib/validate.js @@ -22,7 +22,7 @@ module.exports = { this.serverless.service.getRegionInStage(this.options.stage, this.options.region); // validate that path and method exists for each http event in service - forEach(this.serverless.service.functions, (functionObject) => { + forEach(this.serverless.service.functions, (functionObject, functionName) => { functionObject.events.forEach(event => { if (event.http) { let method; @@ -35,15 +35,34 @@ module.exports = { method = event.http.split(' ')[0]; path = event.http.split(' ')[1]; } - - // TODO validate the values of these properties as well + if (!path) { + const errorMessage = [ + `Missing "path" property in function "${functionName}" for http event in serverless.yaml.`, + ` If you define an http event, make sure you pass a valid value for it,`, + ` either as string syntax, or object syntax.`, + ` Please check the docs for more options.` + ].join(''); throw new this.serverless.classes - .Error('Missing "path" property in serverless.yaml for http event.'); + .Error(errorMessage); } if (!method) { + const errorMessage = [ + `Missing "method" property in function "${functionName}" for http event in serverless.yaml.`, + ` If you define an http event, make sure you pass a valid value for it,`, + ` either as string syntax, or object syntax.`, + ` Please check the docs for more options.` + ].join(''); throw new this.serverless.classes - .Error('Missing "method" property in serverless.yaml for http event.'); + .Error(errorMessage); + } + + if (['get', 'post', 'put', 'patch', 'options', 'head', 'delete'].indexOf(method) === -1) { + const errorMessage = [ + `Invalid APIG method "${method}" in function "${functionName}".`, + ` AWS supported methods are: get, post, put, patch, options, head, delete.` + ].join(''); + throw new this.serverless.classes.Error(errorMessage); } } }); diff --git a/lib/plugins/aws/deploy/compile/events/s3/index.js b/lib/plugins/aws/deploy/compile/events/s3/index.js index 2cba0895e..238082b56 100644 --- a/lib/plugins/aws/deploy/compile/events/s3/index.js +++ b/lib/plugins/aws/deploy/compile/events/s3/index.js @@ -30,8 +30,13 @@ class AwsCompileS3Events { if (typeof event.s3 === 'object') { if (!event.s3.bucket) { + const errorMessage = [ + `Missing "bucket" property for s3 event in function ${functionName}.`, + ` The correct syntax is: s3: bucketName OR an object with "bucket" property.`, + ` Please check the docs for more info.` + ].join(''); throw new this.serverless.classes - .Error(`Missing "bucket" property in s3 event in function ${functionName}`); + .Error(errorMessage); } BucketName = event.s3.bucket + i; if (event.s3.event) { @@ -40,8 +45,13 @@ class AwsCompileS3Events { } else if (typeof event.s3 === 'string') { BucketName = event.s3 + i; } else { + const errorMessage = [ + `S3 event of function ${functionName} is not an object nor a string.`, + ` The correct syntax is: s3: bucketName OR an object with "bucket" property.`, + ` Please check the docs for more info.` + ].join(''); throw new this.serverless.classes - .Error(`S3 event of function ${functionName} is not an object nor a string`); + .Error(errorMessage); } const bucketTemplate = ` { diff --git a/lib/plugins/aws/deploy/compile/events/schedule/index.js b/lib/plugins/aws/deploy/compile/events/schedule/index.js index 024d0a789..eea373028 100644 --- a/lib/plugins/aws/deploy/compile/events/schedule/index.js +++ b/lib/plugins/aws/deploy/compile/events/schedule/index.js @@ -30,8 +30,13 @@ class AwsCompileScheduledEvents { // TODO validate rate syntax if (typeof event.schedule === 'object') { if (!event.schedule.rate) { + const errorMessage = [ + `Missing "rate" property for schedule event in function ${functionName}`, + ` The correct syntax is: schedule: rate(10 minutes) OR an object with "rate" property.`, + ` Please check the docs for more info.` + ].join(''); throw new this.serverless.classes - .Error(`Missing "rate" property in schedule event in function ${functionName}`); + .Error(errorMessage); } ScheduleExpression = event.schedule.rate; State = event.schedule.enabled ? 'ENABLED' : 'DISABLED'; @@ -39,8 +44,13 @@ class AwsCompileScheduledEvents { ScheduleExpression = event.schedule; State = 'ENABLED'; } else { + const errorMessage = [ + `Schedule event of function ${functionName} is not an object nor a string`, + ` The correct syntax is: schedule: rate(10 minutes) OR an object with "rate" property.`, + ` Please check the docs for more info.` + ].join(''); throw new this.serverless.classes - .Error(`Schedule event of function ${functionName} is not an object nor a string`); + .Error(errorMessage); } const scheduleTemplate = ` diff --git a/lib/plugins/aws/deploy/compile/functions/index.js b/lib/plugins/aws/deploy/compile/functions/index.js index 88b771078..f0a9a67d6 100644 --- a/lib/plugins/aws/deploy/compile/functions/index.js +++ b/lib/plugins/aws/deploy/compile/functions/index.js @@ -47,19 +47,24 @@ class AwsCompileFunctions { .S3Key = ''; // will be replaced in a further step if (!functionObject.handler) { + const errorMessage = [ + `Missing "handler" property in function ${functionName}`, + ` Please make sure you point to the correct lambda handler.`, + ` For example: handler.hello.`, + ` Please check the docs for more info` + ].join(''); throw new this.serverless.classes - .Error(`Missing "handler" property in function ${functionName}`); + .Error(errorMessage); } - - // TODO validate the values of each of those properties + const Handler = functionObject.handler; const FunctionName = functionObject.name || `${this.serverless.service.service}-${this.options.stage}-${functionName}`; - const MemorySize = functionObject.memory - || this.serverless.service.defaults.memory + const MemorySize = Number(functionObject.memory) + || Number(this.serverless.service.defaults.memory) || 1024; - const Timeout = functionObject.timeout - || this.serverless.service.defaults.timeout + const Timeout = Number(functionObject.timeout) + || Number(this.serverless.service.defaults.timeout) || 6; newFunction.Properties.Handler = Handler; diff --git a/lib/plugins/aws/deploy/lib/deployFunctions.js b/lib/plugins/aws/deploy/lib/deployFunctions.js index 6698f0166..041ad0b9b 100644 --- a/lib/plugins/aws/deploy/lib/deployFunctions.js +++ b/lib/plugins/aws/deploy/lib/deployFunctions.js @@ -51,7 +51,12 @@ module.exports = { const zipFileName = `${func.name}-${(new Date).getTime().toString()}.zip`; if (!handlerFullPath.endsWith(func.handler)) { - throw new this.serverless.classes.Error(`The handler ${func.handler} was not found`); + const errorMessage = [ + `The handler ${func.handler} was not found.`, + ` Please make sure you have this handler in your service at the referenced location.`, + ` Please check the docs for more info` + ].join(''); + throw new this.serverless.classes.Error(errorMessage); } const packageRoot = handlerFullPath.replace(func.handler, ''); diff --git a/lib/plugins/aws/deploy/lib/validate.js b/lib/plugins/aws/deploy/lib/validate.js index e11ffee1e..cc666a8d2 100644 --- a/lib/plugins/aws/deploy/lib/validate.js +++ b/lib/plugins/aws/deploy/lib/validate.js @@ -5,7 +5,7 @@ const BbPromise = require('bluebird'); module.exports = { validate() { if (!this.serverless.config.servicePath) { - throw new this.serverless.classes.Error('This command can only be run inside a service'); + throw new this.serverless.classes.Error('This command can only be run inside a service directory'); } this.options.stage = this.options.stage @@ -19,12 +19,6 @@ module.exports = { this.serverless.service.getStage(this.options.stage); this.serverless.service.getRegionInStage(this.options.stage, this.options.region); - if (Object.keys(this.serverless.service.environment - .stages[this.options.stage].regions[this.options.region]).indexOf('vars') === -1) { - throw new this.serverless.classes - .Error('region vars object does not exist in serverless.env.yaml'); - } - return BbPromise.resolve(); }, }; diff --git a/lib/plugins/aws/deploy/tests/validate.js b/lib/plugins/aws/deploy/tests/validate.js index 7222a0aaa..ffd29b041 100644 --- a/lib/plugins/aws/deploy/tests/validate.js +++ b/lib/plugins/aws/deploy/tests/validate.js @@ -54,10 +54,5 @@ describe('#validate()', () => { awsDeploy.serverless.config.servicePath = false; expect(() => awsDeploy.validate()).to.throw(Error); }); - - it('should throw error if region vars object does not exist', () => { - awsDeploy.serverless.service.environment.stages.dev.regions['us-east-1'] = {}; - expect(() => awsDeploy.validate()).to.throw(Error); - }); }); diff --git a/lib/plugins/aws/invoke/index.js b/lib/plugins/aws/invoke/index.js index b574e4d75..13b68f062 100644 --- a/lib/plugins/aws/invoke/index.js +++ b/lib/plugins/aws/invoke/index.js @@ -40,7 +40,7 @@ class AwsInvoke { if (this.options.path) { if (!this.serverless.utils .fileExistsSync(path.join(this.serverless.config.servicePath, this.options.path))) { - throw new this.serverless.classes.Error('The file path you provided does not exist.'); + throw new this.serverless.classes.Error('The file you provided does not exist.'); } this.options.data = this.serverless.utils diff --git a/lib/plugins/create/create.js b/lib/plugins/create/create.js index 995a310ea..fad7f9bd9 100644 --- a/lib/plugins/create/create.js +++ b/lib/plugins/create/create.js @@ -49,7 +49,11 @@ class Create { } if (['aws', 'azure', 'google', 'ibm'].indexOf(this.options.provider)) { - throw new this.serverless.classes.Error('Please provide a valid provider.'); + const errorMessage = [ + `Provider "${this.options.provider}" is not supported.`, + ` Valid values for provider are: aws, azure, google, ibm.` + ].join(''); + throw new this.serverless.classes.Error(errorMessage); } this.serverless.config diff --git a/tests/classes/Service.js b/tests/classes/Service.js index 4e51b1cce..672a81a0f 100644 --- a/tests/classes/Service.js +++ b/tests/classes/Service.js @@ -507,6 +507,45 @@ describe('Service', () => { }); }); + it('should throw error if provider property is invalid', () => { + const SUtils = new Utils(); + const tmpDirPath = path.join(os.tmpdir(), (new Date).getTime().toString()); + const serverlessYaml = { + service: 'service-name', + provider: 'invalid', + functions: {}, + }; + const serverlessEnvYaml = { + vars: {}, + stages: { + dev: { + vars: {}, + regions: {}, + }, + }, + }; + + serverlessEnvYaml.stages.dev.regions['us-east-1'] = { + vars: {}, + }; + + SUtils.writeFileSync(path.join(tmpDirPath, 'serverless.yaml'), + YAML.dump(serverlessYaml)); + SUtils.writeFileSync(path.join(tmpDirPath, 'serverless.env.yaml'), + YAML.dump(serverlessEnvYaml)); + + const serverless = new Serverless({ servicePath: tmpDirPath }); + serviceInstance = new Service(serverless); + + return serviceInstance.load().then(() => { + // if we reach this, then no error was thrown as expected + // so make assertion fail intentionally to let us know something is wrong + expect(1).to.equal(2); + }).catch(e => { + expect(e.name).to.be.equal('ServerlessError'); + }); + }); + it('should throw error if functions property is missing', () => { const SUtils = new Utils(); const tmpDirPath = path.join(os.tmpdir(), (new Date).getTime().toString()); From 356127b8308b508b1dd297d4b24026e854422f28 Mon Sep 17 00:00:00 2001 From: "Eslam A. Hefnawy" Date: Thu, 30 Jun 2016 13:50:37 +0200 Subject: [PATCH 2/3] fix linting issues --- lib/classes/Error.js | 4 +-- lib/classes/PluginManager.js | 2 +- lib/classes/Service.js | 32 +++++++++++-------- .../compile/events/apiGateway/lib/methods.js | 5 +-- .../events/apiGateway/lib/permissions.js | 5 +-- .../events/apiGateway/lib/resources.js | 5 +-- .../compile/events/apiGateway/lib/validate.js | 22 +++++++------ .../aws/deploy/compile/events/s3/index.js | 8 ++--- .../deploy/compile/events/schedule/index.js | 10 +++--- .../aws/deploy/compile/functions/index.js | 8 ++--- lib/plugins/aws/deploy/lib/deployFunctions.js | 4 +-- lib/plugins/aws/deploy/lib/validate.js | 3 +- lib/plugins/create/create.js | 2 +- 13 files changed, 62 insertions(+), 48 deletions(-) diff --git a/lib/classes/Error.js b/lib/classes/Error.js index 78c18a12d..ce8f4bf5a 100644 --- a/lib/classes/Error.js +++ b/lib/classes/Error.js @@ -25,7 +25,7 @@ module.exports.logError = (e) => { consoleLog(chalk.yellow(` ${errorType} ${line}`)); consoleLog(' '); - // for + // format error message to fit neatly const words = e.message.split(' '); let logLine = []; words.forEach(word => { @@ -37,7 +37,7 @@ module.exports.logError = (e) => { } }); - if (logLine.length != 0) { + if (logLine.length !== 0) { consoleLog(chalk.yellow(` ${logLine.join(' ')}`)); } diff --git a/lib/classes/PluginManager.js b/lib/classes/PluginManager.js index 3e229e7a7..ca8ad2922 100644 --- a/lib/classes/PluginManager.js +++ b/lib/classes/PluginManager.js @@ -34,7 +34,7 @@ class PluginManager { if (!this.commands[commandsArray[0]]) { const errorMessage = [ `command "${commandsArray[0]}" not found`, - ` Run "sls help" for a list of all available commands.` + ' Run "sls help" for a list of all available commands.', ].join(); throw new this.serverless.classes.Error(errorMessage); } diff --git a/lib/classes/Service.js b/lib/classes/Service.js index b8ae4ff6e..5fcb0a3b8 100644 --- a/lib/classes/Service.js +++ b/lib/classes/Service.js @@ -57,8 +57,8 @@ class Service { if (['aws', 'azure', 'google', 'ibm'].indexOf(serverlessYaml.provider)) { const errorMessage = [ `Provider "${serverlessYaml.provider}" is not supported.`, - ` Valid values for provider are: aws, azure, google, ibm.`, - ` Please provide one of those values to the "provider" property in serverless.yaml.` + ' Valid values for provider are: aws, azure, google, ibm.', + ' Please provide one of those values to the "provider" property in serverless.yaml.', ].join(''); throw new SError(errorMessage); } @@ -178,7 +178,7 @@ class Service { if (!value && !value !== '') { const errorMessage = [ `Variable "${variableName}" doesn't exist in serverless.env.yaml.`, - ` Please add it to serverless.env.yaml.` + ' Please add it to serverless.env.yaml.', ].join(''); throw new that.serverless.classes .Error(errorMessage); @@ -186,8 +186,9 @@ class Service { if (variableString.split('.').length > 1) { const errorMessage = [ `Trying to access sub properties of a string variable "${variableName}".`, - ` Please make sure the variable in serverless.env.yaml`, - ` is an object, otherwise you can't use the dot notation for that variable in serverless.yaml` + ' Please make sure the variable in serverless.env.yaml', + ' is an object, otherwise you cannot use the', + ' dot notation for that variable in serverless.yaml', ].join(''); throw new that.serverless.classes .Error(errorMessage); @@ -205,8 +206,9 @@ class Service { if (!value[subProperty]) { const errorMessage = [ `Variable "${variableName}" doesn't have sub property "${subProperty}".`, - ` Please make sure the variable is the intended object in serverless.env.yaml,`, - ` or reference the correct sub property in serverless.yaml` + ' Please make sure the variable is', + ' the intended object in serverless.env.yaml,', + ' or reference the correct sub property in serverless.yaml', ].join(''); throw new that.serverless.classes .Error(errorMessage); @@ -219,8 +221,10 @@ class Service { } else { if (val !== variableSyntax) { const errorMessage = [ - `Trying to populate non string variables into a string for variable "${variableName}".`, - ` Please make sure the variable value in serverless.env.yaml is a string` + 'Trying to populate non string variables into', + ` a string for variable "${variableName}".`, + ' Please make sure the variable value in', + ' serverless.env.yaml is a string', ].join(''); throw new that.serverless.classes .Error(errorMessage); @@ -230,16 +234,18 @@ class Service { } else if (variableString.split('.').length > 1) { const errorMessage = [ `Trying to access sub properties of a non-object variable "${variableName}"`, - ` Please make sure the variable is an object in serverless.env.yaml,`, - ` otherwise, you can't use the dot notation for that variable in serverless.yaml` + ' Please make sure the variable is an object in serverless.env.yaml,', + ' otherwise, you cannot use the dot notation', + ' for that variable in serverless.yaml', ].join(''); throw new that.serverless.classes .Error(errorMessage); } else { if (val !== variableSyntax) { const errorMessage = [ - `Trying to populate non string variables into a string for variable "${variableName}".`, - ` Please make sure the variable value in serverless.env.yaml is a string` + 'Trying to populate non string variables', + ` into a string for variable "${variableName}".`, + ' Please make sure the variable value in serverless.env.yaml is a string', ].join(''); throw new that.serverless.classes .Error(errorMessage); diff --git a/lib/plugins/aws/deploy/compile/events/apiGateway/lib/methods.js b/lib/plugins/aws/deploy/compile/events/apiGateway/lib/methods.js index cc769de58..2a8f39221 100644 --- a/lib/plugins/aws/deploy/compile/events/apiGateway/lib/methods.js +++ b/lib/plugins/aws/deploy/compile/events/apiGateway/lib/methods.js @@ -20,8 +20,9 @@ module.exports = { } else { const errorMessage = [ `HTTP event of function ${functionName} is not an object nor a string.`, - ` The correct syntax is: http: get users/list OR an object with "path" and "method" proeprties.`, - ` Please check the docs for more info.` + ' The correct syntax is: http: get users/list', + ' OR an object with "path" and "method" proeprties.', + ' Please check the docs for more info.', ].join(''); throw new this.serverless.classes .Error(errorMessage); diff --git a/lib/plugins/aws/deploy/compile/events/apiGateway/lib/permissions.js b/lib/plugins/aws/deploy/compile/events/apiGateway/lib/permissions.js index d261b8d45..2ec265a44 100644 --- a/lib/plugins/aws/deploy/compile/events/apiGateway/lib/permissions.js +++ b/lib/plugins/aws/deploy/compile/events/apiGateway/lib/permissions.js @@ -20,8 +20,9 @@ module.exports = { } else { const errorMessage = [ `HTTP event of function ${functionName} is not an object nor a string.`, - ` The correct syntax is: http: get users/list OR an object with "path" and "method" proeprties.`, - ` Please check the docs for more info.` + ' The correct syntax is: http: get users/list', + ' OR an object with "path" and "method" proeprties.', + ' Please check the docs for more info.', ].join(''); throw new this.serverless.classes .Error(errorMessage); diff --git a/lib/plugins/aws/deploy/compile/events/apiGateway/lib/resources.js b/lib/plugins/aws/deploy/compile/events/apiGateway/lib/resources.js index ed13d5d8e..83981c9be 100644 --- a/lib/plugins/aws/deploy/compile/events/apiGateway/lib/resources.js +++ b/lib/plugins/aws/deploy/compile/events/apiGateway/lib/resources.js @@ -20,8 +20,9 @@ module.exports = { } else { const errorMessage = [ `HTTP event of function ${functionName} is not an object nor a string.`, - ` The correct syntax is: http: get users/list OR an object with "path" and "method" proeprties.`, - ` Please check the docs for more info.` + ' The correct syntax is: http: get users/list', + ' OR an object with "path" and "method" proeprties.', + ' Please check the docs for more info.', ].join(''); throw new this.serverless.classes .Error(errorMessage); diff --git a/lib/plugins/aws/deploy/compile/events/apiGateway/lib/validate.js b/lib/plugins/aws/deploy/compile/events/apiGateway/lib/validate.js index 71636bdb5..ec526384b 100644 --- a/lib/plugins/aws/deploy/compile/events/apiGateway/lib/validate.js +++ b/lib/plugins/aws/deploy/compile/events/apiGateway/lib/validate.js @@ -35,23 +35,25 @@ module.exports = { method = event.http.split(' ')[0]; path = event.http.split(' ')[1]; } - + if (!path) { const errorMessage = [ - `Missing "path" property in function "${functionName}" for http event in serverless.yaml.`, - ` If you define an http event, make sure you pass a valid value for it,`, - ` either as string syntax, or object syntax.`, - ` Please check the docs for more options.` + `Missing "path" property in function "${functionName}"`, + ' for http event in serverless.yaml.', + ' If you define an http event, make sure you pass a valid value for it,', + ' either as string syntax, or object syntax.', + ' Please check the docs for more options.', ].join(''); throw new this.serverless.classes .Error(errorMessage); } if (!method) { const errorMessage = [ - `Missing "method" property in function "${functionName}" for http event in serverless.yaml.`, - ` If you define an http event, make sure you pass a valid value for it,`, - ` either as string syntax, or object syntax.`, - ` Please check the docs for more options.` + `Missing "method" property in function "${functionName}"`, + ' for http event in serverless.yaml.', + ' If you define an http event, make sure you pass a valid value for it,', + ' either as string syntax, or object syntax.', + ' Please check the docs for more options.', ].join(''); throw new this.serverless.classes .Error(errorMessage); @@ -60,7 +62,7 @@ module.exports = { if (['get', 'post', 'put', 'patch', 'options', 'head', 'delete'].indexOf(method) === -1) { const errorMessage = [ `Invalid APIG method "${method}" in function "${functionName}".`, - ` AWS supported methods are: get, post, put, patch, options, head, delete.` + ' AWS supported methods are: get, post, put, patch, options, head, delete.', ].join(''); throw new this.serverless.classes.Error(errorMessage); } diff --git a/lib/plugins/aws/deploy/compile/events/s3/index.js b/lib/plugins/aws/deploy/compile/events/s3/index.js index 238082b56..a14470db7 100644 --- a/lib/plugins/aws/deploy/compile/events/s3/index.js +++ b/lib/plugins/aws/deploy/compile/events/s3/index.js @@ -32,8 +32,8 @@ class AwsCompileS3Events { if (!event.s3.bucket) { const errorMessage = [ `Missing "bucket" property for s3 event in function ${functionName}.`, - ` The correct syntax is: s3: bucketName OR an object with "bucket" property.`, - ` Please check the docs for more info.` + ' The correct syntax is: s3: bucketName OR an object with "bucket" property.', + ' Please check the docs for more info.', ].join(''); throw new this.serverless.classes .Error(errorMessage); @@ -47,8 +47,8 @@ class AwsCompileS3Events { } else { const errorMessage = [ `S3 event of function ${functionName} is not an object nor a string.`, - ` The correct syntax is: s3: bucketName OR an object with "bucket" property.`, - ` Please check the docs for more info.` + ' The correct syntax is: s3: bucketName OR an object with "bucket" property.', + ' Please check the docs for more info.', ].join(''); throw new this.serverless.classes .Error(errorMessage); diff --git a/lib/plugins/aws/deploy/compile/events/schedule/index.js b/lib/plugins/aws/deploy/compile/events/schedule/index.js index eea373028..e4008d9d9 100644 --- a/lib/plugins/aws/deploy/compile/events/schedule/index.js +++ b/lib/plugins/aws/deploy/compile/events/schedule/index.js @@ -32,8 +32,9 @@ class AwsCompileScheduledEvents { if (!event.schedule.rate) { const errorMessage = [ `Missing "rate" property for schedule event in function ${functionName}`, - ` The correct syntax is: schedule: rate(10 minutes) OR an object with "rate" property.`, - ` Please check the docs for more info.` + ' The correct syntax is: schedule: rate(10 minutes)', + ' OR an object with "rate" property.', + ' Please check the docs for more info.', ].join(''); throw new this.serverless.classes .Error(errorMessage); @@ -46,8 +47,9 @@ class AwsCompileScheduledEvents { } else { const errorMessage = [ `Schedule event of function ${functionName} is not an object nor a string`, - ` The correct syntax is: schedule: rate(10 minutes) OR an object with "rate" property.`, - ` Please check the docs for more info.` + ' The correct syntax is: schedule: rate(10 minutes)', + ' OR an object with "rate" property.', + ' Please check the docs for more info.', ].join(''); throw new this.serverless.classes .Error(errorMessage); diff --git a/lib/plugins/aws/deploy/compile/functions/index.js b/lib/plugins/aws/deploy/compile/functions/index.js index f0a9a67d6..4b6f6cd8d 100644 --- a/lib/plugins/aws/deploy/compile/functions/index.js +++ b/lib/plugins/aws/deploy/compile/functions/index.js @@ -49,14 +49,14 @@ class AwsCompileFunctions { if (!functionObject.handler) { const errorMessage = [ `Missing "handler" property in function ${functionName}`, - ` Please make sure you point to the correct lambda handler.`, - ` For example: handler.hello.`, - ` Please check the docs for more info` + ' Please make sure you point to the correct lambda handler.', + ' For example: handler.hello.', + ' Please check the docs for more info', ].join(''); throw new this.serverless.classes .Error(errorMessage); } - + const Handler = functionObject.handler; const FunctionName = functionObject.name || `${this.serverless.service.service}-${this.options.stage}-${functionName}`; diff --git a/lib/plugins/aws/deploy/lib/deployFunctions.js b/lib/plugins/aws/deploy/lib/deployFunctions.js index 041ad0b9b..238b8ba36 100644 --- a/lib/plugins/aws/deploy/lib/deployFunctions.js +++ b/lib/plugins/aws/deploy/lib/deployFunctions.js @@ -53,8 +53,8 @@ module.exports = { if (!handlerFullPath.endsWith(func.handler)) { const errorMessage = [ `The handler ${func.handler} was not found.`, - ` Please make sure you have this handler in your service at the referenced location.`, - ` Please check the docs for more info` + ' Please make sure you have this handler in your service at the referenced location.', + ' Please check the docs for more info', ].join(''); throw new this.serverless.classes.Error(errorMessage); } diff --git a/lib/plugins/aws/deploy/lib/validate.js b/lib/plugins/aws/deploy/lib/validate.js index cc666a8d2..4a81e17b7 100644 --- a/lib/plugins/aws/deploy/lib/validate.js +++ b/lib/plugins/aws/deploy/lib/validate.js @@ -5,7 +5,8 @@ const BbPromise = require('bluebird'); module.exports = { validate() { if (!this.serverless.config.servicePath) { - throw new this.serverless.classes.Error('This command can only be run inside a service directory'); + throw new this.serverless.classes + .Error('This command can only be run inside a service directory'); } this.options.stage = this.options.stage diff --git a/lib/plugins/create/create.js b/lib/plugins/create/create.js index fad7f9bd9..d1bddeceb 100644 --- a/lib/plugins/create/create.js +++ b/lib/plugins/create/create.js @@ -51,7 +51,7 @@ class Create { if (['aws', 'azure', 'google', 'ibm'].indexOf(this.options.provider)) { const errorMessage = [ `Provider "${this.options.provider}" is not supported.`, - ` Valid values for provider are: aws, azure, google, ibm.` + ' Valid values for provider are: aws, azure, google, ibm.', ].join(''); throw new this.serverless.classes.Error(errorMessage); } From 7e019f6aa7f3c8afe8a660fb2c7ba21fc4dfd84d Mon Sep 17 00:00:00 2001 From: "Eslam A. Hefnawy" Date: Thu, 30 Jun 2016 15:34:21 +0200 Subject: [PATCH 3/3] replace sls with serverless --- lib/classes/PluginManager.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/classes/PluginManager.js b/lib/classes/PluginManager.js index ca8ad2922..8e711a802 100644 --- a/lib/classes/PluginManager.js +++ b/lib/classes/PluginManager.js @@ -34,7 +34,7 @@ class PluginManager { if (!this.commands[commandsArray[0]]) { const errorMessage = [ `command "${commandsArray[0]}" not found`, - ' Run "sls help" for a list of all available commands.', + ' Run "serverless help" for a list of all available commands.', ].join(); throw new this.serverless.classes.Error(errorMessage); }