Search code examples
asynchronousmeteornpmnode-fibers

Meteor doesn't throw error but crashes


I want to implement error handling in my app but when I throw a Meteor.Error my server crashes. This might be because I'm using a future to wait for the result. How can I get this running?

Meteor.methods({
  '/app/pdf/download': function (url, name) {
    check(url, String);
    check(name, Match.Any);

    if ( ! name) {
      name = url.split('/').pop();
    } else {
      name += '.pdf';
    }

    var Future = Meteor.npmRequire('fibers/future');
    var Download = Meteor.npmRequire('download');

    var future = new Future();

    var download = new Download({ extract: true, strip: 1 })
      .get(url)
      .dest(process.env.PWD + '/staticFiles')
      .rename(name);

    // Run download
    download.run(function (err, files, stream) {
      if (err) {
        throw new Meteor.Error(500, 'Couldn\'t download file');
      }

      future.return(name);
    });

    return future.wait();
  }
});

Solution

  • Yes, it is because you are throwing it in another call stack.

    You could try:

    var error;
    
    download.run(function (err, files, stream) {
      if (err) {
        error = err;
      }
    
      future.return(name);
    });
    
    var result = future.wait();
    
    if (error)
        throw new Meteor.Error(500, 'Couldn\'t download file');
    
    return result;
    

    Either way I recommend using Meteor.wrapAsync for your purpose.

     var sync = Meteor.wrapAsync(function (done) {
        download.run(function (err, files, stream) {
          if (err) {
            done(new Meteor.Error(500, 'Couldn\'t download file'));
          }
          else {
            done(err, name);
          }
        });
     };
    
     return sync();
    

    If you are using Meteor < 1.0, its Meteor._wrapAsync().