diff --git a/backend/.nycrc.json b/backend/.nycrc.json index a3b43e20..fa289571 100644 --- a/backend/.nycrc.json +++ b/backend/.nycrc.json @@ -8,7 +8,7 @@ "report-dir": "./reports/coverage", "check-coverage": true, "branches": 26, - "lines": 39, + "lines": 38, "functions": 29, "statements": 39 } diff --git a/backend/package.json b/backend/package.json index b22f3499..eb92d56f 100644 --- a/backend/package.json +++ b/backend/package.json @@ -5,7 +5,7 @@ "license": "Apache 2.0", "description": "Provide rich user experience for Yeoman generators using VSCode extension or the browser", "repository": "https://github.com/SAP/yeoman-ui", - "version": "0.0.31", + "version": "0.0.32", "engines": { "vscode": "^1.39.2" }, diff --git a/backend/src/yeomanui.ts b/backend/src/yeomanui.ts index 588dafa4..e64e2f6d 100644 --- a/backend/src/yeomanui.ts +++ b/backend/src/yeomanui.ts @@ -176,7 +176,9 @@ export class YeomanUI { this.doGeneratorDone(true, message, destinationRoot); }); } catch (error) { - this.handleError(error); + const errorMessage = `Error info ---->\n ${this.getErrorInfo(error)}`; + this.showMessageInOutput(errorMessage); + return Promise.reject(errorMessage); } } @@ -192,10 +194,8 @@ export class YeomanUI { return `name: ${name}\n message: ${message}\n stack: ${stack}\n string: ${string}\n`; } - handleError(error: any) { - const errorMessage = `Error info ---->\n ${this.getErrorInfo(error)}`; - console.error(errorMessage); - this.logMessage(errorMessage); + async showMessageInOutput(errorMessage: string) { + await this.logMessage(errorMessage); this.toggleLog(); } @@ -212,20 +212,23 @@ export class YeomanUI { * @param answers - partial answers for the current prompt -- the input parameter to the method to be evaluated * @param method */ - public evaluateMethod(params: any[], questionName: string, methodName: string): any { + public async evaluateMethod(params: any[], questionName: string, methodName: string): Promise { try { if (this.currentQuestions) { const relevantQuestion: any = _.find(this.currentQuestions, question => { return (_.get(question, "name") === questionName); }); if (relevantQuestion) { - return relevantQuestion[methodName].apply(this.gen, params); + return await relevantQuestion[methodName].apply(this.gen, params); } } } catch (error) { - this.handleError(error); + const questionInfo = `Could not update method '${methodName}' in '${questionName}' question in generator '${this.gen.options.namespace}'`; + const errorMessage = `${questionInfo}\nError info ---->\n ${this.getErrorInfo(error)}`; + this.showMessageInOutput(errorMessage); + return Promise.reject(errorMessage); } - } +} public async receiveIsWebviewReady() { // TODO: loading generators takes a long time; consider prefetching list of generators diff --git a/frontend/src/App.vue b/frontend/src/App.vue index 7c7fa5f1..133d482e 100644 --- a/frontend/src/App.vue +++ b/frontend/src/App.vue @@ -168,7 +168,10 @@ export default { let showBusy = true const that = this const finished = relevantQuestionsToUpdate.reduce((p, question) => { - return p.then(() => that.updateQuestion(question)) + return p.then(() => that.updateQuestion(question)).catch(error => { + // eslint-disable-next-line no-console + console.error(error); + }) }, Promise.resolve()); setTimeout(() => { @@ -188,70 +191,59 @@ export default { }, async updateQuestion(question) { const newAnswers = this.currentPrompt.answers - try { - if (question.when === FUNCTION) { - question.isWhen = await this.rpc.invoke("evaluateMethod", [ - [newAnswers], + if (question.when === FUNCTION) { + question.isWhen = await this.rpc.invoke("evaluateMethod", [ + [newAnswers], + question.name, + "when" + ]); + } + + if (question.isWhen === true) { + if (question.filter === FUNCTION) { + question.answer = await this.rpc.invoke("evaluateMethod", [ + [question.answer], question.name, - "when" + "filter" ]); } - - if (question.isWhen === true) { - if (question.filter === FUNCTION) { - question.answer = await this.rpc.invoke("evaluateMethod", [ - [question.answer], - question.name, - "filter" - ]); - } - if (question._default === FUNCTION) { - question.default = await this.rpc.invoke("evaluateMethod", [ - [newAnswers], - question.name, - "default" - ]); - if (question.answer === undefined) { - question.answer = question.default; - } - } - if (question._message === FUNCTION) { - question.message = await this.rpc.invoke("evaluateMethod", [ - [newAnswers], - question.name, - "message" - ]); - } - if (question._choices === FUNCTION) { - question.choices = await this.rpc.invoke("evaluateMethod", [ - [newAnswers], - question.name, - "choices" - ]); - } - if (question.validate === FUNCTION) { - const response = await this.rpc.invoke("evaluateMethod", [ - [question.answer, newAnswers], - question.name, - "validate" - ]); - question.isValid = _.isString(response) ? false : response; - question.validationMessage = _.isString(response) - ? response - : undefined; + if (question._default === FUNCTION) { + question.default = await this.rpc.invoke("evaluateMethod", [ + [newAnswers], + question.name, + "default" + ]); + if (question.answer === undefined) { + question.answer = question.default; } } - } catch (error) { - const errorMessage = this.getErrorMessageOnException(question, error); - // eslint-disable-next-line no-console - console.error(errorMessage); - await this.rpc.invoke("logMessage", [errorMessage]); - this.rpc.invoke("toggleLog", [{}]); + if (question._message === FUNCTION) { + question.message = await this.rpc.invoke("evaluateMethod", [ + [newAnswers], + question.name, + "message" + ]); + } + if (question._choices === FUNCTION) { + question.choices = await this.rpc.invoke("evaluateMethod", [ + [newAnswers], + question.name, + "choices" + ]); + } + if (question.validate === FUNCTION) { + const response = await this.rpc.invoke("evaluateMethod", [ + [question.answer, newAnswers], + question.name, + "validate" + ]); + question.isValid = _.isString(response) ? false : response; + question.validationMessage = _.isString(response) + ? response + : undefined; + } } }, - getErrorMessageOnException(question) { - return `Could not update the '${question.name}' question in generator '${this.generatorName}`; - }, next() { if (this.resolve) { try { diff --git a/frontend/tests/App.spec.js b/frontend/tests/App.spec.js index 4931267d..672ce137 100644 --- a/frontend/tests/App.spec.js +++ b/frontend/tests/App.spec.js @@ -163,8 +163,6 @@ describe('App.vue', () => { const invokeSpy = jest.spyOn(wrapper.vm.rpc, 'invoke') await wrapper.vm.updateQuestionsFromIndex(0) expect(invokeSpy).toHaveBeenCalledWith('evaluateMethod', [["validateAnswer", {"validateQ": "validateAnswer"}], 'validateQ', 'validate']) - expect(invokeSpy).toHaveBeenCalledWith('toggleLog', [{}]) - invokeSpy.mockRestore(); }) @@ -184,7 +182,6 @@ describe('App.vue', () => { const invokeSpy = jest.spyOn(wrapper.vm.rpc, 'invoke') await wrapper.vm.updateQuestionsFromIndex(0) expect(invokeSpy).toHaveBeenCalledWith('evaluateMethod', [["validateAnswer", {"validateQ": "validateAnswer"}], 'validateQ', 'validate']) - expect(invokeSpy).toHaveBeenCalledWith('toggleLog', [{}]) invokeSpy.mockRestore(); }) @@ -205,7 +202,6 @@ describe('App.vue', () => { const invokeSpy = jest.spyOn(wrapper.vm.rpc, 'invoke') await wrapper.vm.updateQuestionsFromIndex(0) expect(invokeSpy).toHaveBeenCalledWith('evaluateMethod', [["validateAnswer", {"validateQ": "validateAnswer"}], 'validateQ', 'validate']) - expect(invokeSpy).toHaveBeenCalledWith('toggleLog', [{}]) invokeSpy.mockRestore(); })