Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to gracefully abort yeoman generator on error?

Tags:

I'm writing a yeoman generator and want to check some prerequisites, for example a git being installed. I can easily check this using .exec, but how do i gracefully abort generator and report error to user? I searched docs, but it seems that i'm missing some obvious way to do it. Any hints?

Throwing exception will of course abort generator, but is it a best way? Maybe something more user friendly? Not all yeoman users are able to read js exceptions.

like image 969
grigoryvp Avatar asked Dec 23 '14 08:12

grigoryvp


1 Answers

The current state of error handling in the popular generators is quite diverse:

  • in the most cases they just log the error and return from the action and let the subsequnt actions run and return 0 status code:

    generator-karma's setupTravis method:

    if (err) {     this.log.error('Could not open package.json for reading.', err);     done();     return; 

    }

  • or set a custom abort property on error and skip further actions with cheking on the abort property but still return 0 status code:

    generator-jhipster's CloudFoundryGenerator:

    CloudFoundryGenerator.prototype.checkInstallation = function checkInstallation() {     if(this.abort) return;     var done = this.async();      exec('cf --version', function (err) {         if (err) {             this.log.error('cloudfoundry\'s cf command line interface is not available. ' +         'You can install it via https://github.com/cloudfoundry/cli/releases');             this.abort = true;         }         done();     }.bind(this)); }; 
  • or manually end the process with process.exit:

    generator-mobile's configuringmethod:

    if (err) {       self.log.error(err);       process.exit(1); } 

However none of these methods provide a good way to signal to the environment that something went wrong except the last one but directly calling process.exit is a design smell.

Throwing an exception is also an option but this presents also the stackstrace to the user which is not always a good idea.

The best option would be use the Environment.error method, which has some nice advantages:

  • the Environment is exposed thorough the env property of the yeoman.generators.Base
  • an error event is emitted which is handled by the yo cli code
  • the execution will result in a non zero (error) status code which is override-able
  • by default yo will display only the message and no stacktrace
  • the stacktrace can be optionally displayed with providing the --debug built-in option when re-running the generator.

With using this technique your action method would look like this:

module.exports = generators.Base.extend({   method1: function () {     console.log('method 1 just ran');     this.env.error("something bad is happened");     console.log('this won't be executed');   },   method2: function () {     console.log('this won't be executed');   } }); 
like image 122
nemesv Avatar answered Sep 23 '22 23:09

nemesv