Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/285.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Node.js 从回调捕获异常_Node.js_Mongodb - Fatal编程技术网

Node.js 从回调捕获异常

Node.js 从回调捕获异常,node.js,mongodb,Node.js,Mongodb,我正在使用,并试图找到一种捕获API回调中可能发生的异常的方法 我知道最好的做法是将代码包装在一个try-catch块中,但在我的特殊情况下,我向用户公开了驱动程序的API,所以我没有那种级别的控制。尽管如此,我仍然需要捕获回调中发生的潜在异常,以便发回相关的错误消息 编辑:进一步解释。 考虑一些“后端即服务”的情况,用户可以在节点中创建在服务器上运行的JS代码。用户代码可以直接访问db对象(从驱动程序),并可以对其执行任何操作,如编写以下内容: db.collection('test').fi

我正在使用,并试图找到一种捕获API回调中可能发生的异常的方法

我知道最好的做法是将代码包装在一个try-catch块中,但在我的特殊情况下,我向用户公开了驱动程序的API,所以我没有那种级别的控制。尽管如此,我仍然需要捕获回调中发生的潜在异常,以便发回相关的错误消息

编辑:进一步解释。 考虑一些“后端即服务”的情况,用户可以在节点中创建在服务器上运行的JS代码。用户代码可以直接访问
db
对象(从驱动程序),并可以对其执行任何操作,如编写以下内容:

db.collection('test').findOne({ field: 'value' }, function(err, doc){
  throw new Error;
});
我需要以某种方式捕捉到这一点,但是
process.on('uncaughtException')
对我来说太低了。该用户代码是从API请求执行的,因此我希望在其响应中返回相关的错误消息

到目前为止,我已经尝试将错误处理程序(
.on('error')
)添加到
db
对象中,但它没有捕获任何内容。任何帮助都将不胜感激


谢谢

将这一行添加到末尾

process.on('uncaughtException', function (err) {
    console.log(err);
}); 

通过此操作,如果底层存在任何未捕获的异常,服务器将不会停止。

将此行添加到末尾

process.on('uncaughtException', function (err) {
    console.log(err);
}); 

通过这种方式,如果底层存在任何未捕获的异常,服务器将不会停止。

来自MongoDB驱动程序API的任何错误都将作为第一个参数传递给回调。将调用包装在try/catch中对您没有帮助,因为错误是异步发生的。换句话说,对MongoDB API的所有调用都是开始一个异步操作,传入一个回调,在异步操作完成后调用(数据库调用返回)。如果在异步操作期间发生错误,您将无法使用try/catch捕获它。只有库本身能够捕获这些错误,这就是为什么库确保将它们作为第一个参数传递给回调

collection.update({ a : 2 }, { $set: { b : 1 } }, function(err, result) {
  if (err) { /* do error handling */ return; }
  /* err is null, continue as normal */
});
如果我在编写自己的API来封装其中的一些调用,我会采用以下三种方法之一

  • 如果我公开的API是一个回调风格的API,就像MongoDB驱动程序一样,那么我会这样做

    exports.coolFunction = function (callback) {
      collection.update({ a : 2 }, { $set: { b : 1 } }, function (err, result) {
        if (err) { callback(err); return; }
        callback(null, result);
    };
    
    然后有人可以像这样使用我的API:

    var alexLib = require('alexLibExample');
    alexLib.coolFunction(function (err, result) {
      if (err) { /* consumer handles error how they want to in their app */ }
      /* all is good, no errors, continue normally */
    });
    
    var alexLib = require('alexLibExample');
    alexLib.coolFunction().then(function (result) {
      /* do stuff with result */
    }).catch(function (err) {
      /* handle error how user chooses in their app */
    });
    
    var alexLib = require('alexLibExample');
    alexLib.eventEmitter.on('error', function (err) {
      /* user handles error how they choose */
    });
    alexLib.coolFunction(function (result) {
      /* do stuff with result */
    });
    
  • 或者我可以让我的API成为一个承诺支持的API

    var Promise = require('bluebird');
    exports.coolFunction = function () {
      return new Promise(function (resolve, reject) {
        collection.update({ a : 2 }, { $set: { b : 1 } }, function (err, result) {
          if (err) { reject(err); return; }
          resolve(result);
        });
      };
    };
    
    然后有人可以像这样使用我的promise-enabled API:

    var alexLib = require('alexLibExample');
    alexLib.coolFunction(function (err, result) {
      if (err) { /* consumer handles error how they want to in their app */ }
      /* all is good, no errors, continue normally */
    });
    
    var alexLib = require('alexLibExample');
    alexLib.coolFunction().then(function (result) {
      /* do stuff with result */
    }).catch(function (err) {
      /* handle error how user chooses in their app */
    });
    
    var alexLib = require('alexLibExample');
    alexLib.eventEmitter.on('error', function (err) {
      /* user handles error how they choose */
    });
    alexLib.coolFunction(function (result) {
      /* do stuff with result */
    });
    
  • 或者我可以将错误作为错误事件发出,这似乎更符合您的要求

    var EventEmitter = require('events').EventEmitter;
    exports.eventEmitter = new EventEmitter();
    exports.coolFunction = function (callback) {
      collection.update({ a : 2 }, { $set: { b : 1 } }, function (err, result) {
        if (err) { exports.eventEmitter.emit('error', err); return; }
        callback(result);
      });
    };
    
    然后有人可以像这样使用我的事件样式API:

    var alexLib = require('alexLibExample');
    alexLib.coolFunction(function (err, result) {
      if (err) { /* consumer handles error how they want to in their app */ }
      /* all is good, no errors, continue normally */
    });
    
    var alexLib = require('alexLibExample');
    alexLib.coolFunction().then(function (result) {
      /* do stuff with result */
    }).catch(function (err) {
      /* handle error how user chooses in their app */
    });
    
    var alexLib = require('alexLibExample');
    alexLib.eventEmitter.on('error', function (err) {
      /* user handles error how they choose */
    });
    alexLib.coolFunction(function (result) {
      /* do stuff with result */
    });
    
    API的事件样式通常与回调样式相结合。这意味着它们仍然将错误传递给回调函数,这是大多数用户在传递回调时所期望的。然后,它们还发出一个错误事件,作为用户可以订阅的一种全局错误处理程序。我知道这就是工作方式。我可以捕获单个API调用上的错误,也可以设置错误事件处理程序并在那里处理所有错误

    var EventEmitter = require('events').EventEmitter;
    exports.eventEmitter = new EventEmitter();
    exports.coolFunction = function (callback) {
      collection.update({ a : 2 }, { $set: { b : 1 } }, function (err, result) {
        if (err) { exports.eventEmitter.emit('error', err); callback(err); return; }
        callback(null, result);
      });
    };
    
    然后用户在处理错误方面有一定的灵活性

    var alexLib = require('alexLibExample');
    alexLib.eventEmitter.on('error', function (err) {
      /* handle all errors here */
    });
    alexLib.coolFunction(function (err, result) {
      if (err) { return; }
      /* do stuff with result */
    });
    alexLib.coolFunction2(function (err, result) {
      if (err) { /* maybe I have special error handling for this specific call. I can do that here */ }
      /* do stuff with result */
    });
    
  • 如果你真的想得到花式,你可以结合这三种风格

    var EventEmitter = require('events').EventEmitter;
    var Promise = require('bluebird');
    exports.eventEmitter = new EventEmitter();
    exports.coolFunction = function (callback) {
      return new Promise(function (resolve, reject) {
        collection.update({ a : 2 }, { $set: { b : 1 } }, function(err, result) {
          if (err) {
            if (callback) { callback(err); }
            reject(err);
            exports.eventEmitter.emit('error', err);
          }
          if (callback) { callback(err, result); }
          resolve(result);
        });
      });
    };
    
    然后,有人可以随意使用我的API

    var alexLib = require('alexLibExample');
    alexLib.eventEmitter.on('error', function (err) {
      /* handle all errors here */
    });
    alexLib.coolFunction(function (err, result) {
      if (err) {
        /* handle this specific error how user chooses */
      }
      /* do stuff with result */
    });
    
    // or
    
    alexLib.coolFunction().then(function (result) {
      /* do stuff with result */
    }).catch(function (err) {
      /* handle any errors in this promise chain */
    });
    

    来自MongoDB驱动程序API的任何错误都将作为第一个参数传递给回调。将调用包装在try/catch中对您没有帮助,因为错误是异步发生的。换句话说,对MongoDB API的所有调用都是开始一个异步操作,传入一个回调,在异步操作完成后调用(数据库调用返回)。如果在异步操作期间发生错误,您将无法使用try/catch捕获它。只有库本身能够捕获这些错误,这就是为什么库确保将它们作为第一个参数传递给回调

    collection.update({ a : 2 }, { $set: { b : 1 } }, function(err, result) {
      if (err) { /* do error handling */ return; }
      /* err is null, continue as normal */
    });
    
    如果我在编写自己的API来封装其中的一些调用,我会采用以下三种方法之一

  • 如果我公开的API是一个回调风格的API,就像MongoDB驱动程序一样,那么我会这样做

    exports.coolFunction = function (callback) {
      collection.update({ a : 2 }, { $set: { b : 1 } }, function (err, result) {
        if (err) { callback(err); return; }
        callback(null, result);
    };
    
    然后有人可以像这样使用我的API:

    var alexLib = require('alexLibExample');
    alexLib.coolFunction(function (err, result) {
      if (err) { /* consumer handles error how they want to in their app */ }
      /* all is good, no errors, continue normally */
    });
    
    var alexLib = require('alexLibExample');
    alexLib.coolFunction().then(function (result) {
      /* do stuff with result */
    }).catch(function (err) {
      /* handle error how user chooses in their app */
    });
    
    var alexLib = require('alexLibExample');
    alexLib.eventEmitter.on('error', function (err) {
      /* user handles error how they choose */
    });
    alexLib.coolFunction(function (result) {
      /* do stuff with result */
    });
    
  • 或者我可以让我的API成为一个承诺支持的API

    var Promise = require('bluebird');
    exports.coolFunction = function () {
      return new Promise(function (resolve, reject) {
        collection.update({ a : 2 }, { $set: { b : 1 } }, function (err, result) {
          if (err) { reject(err); return; }
          resolve(result);
        });
      };
    };
    
    然后有人可以像这样使用我的promise-enabled API:

    var alexLib = require('alexLibExample');
    alexLib.coolFunction(function (err, result) {
      if (err) { /* consumer handles error how they want to in their app */ }
      /* all is good, no errors, continue normally */
    });
    
    var alexLib = require('alexLibExample');
    alexLib.coolFunction().then(function (result) {
      /* do stuff with result */
    }).catch(function (err) {
      /* handle error how user chooses in their app */
    });
    
    var alexLib = require('alexLibExample');
    alexLib.eventEmitter.on('error', function (err) {
      /* user handles error how they choose */
    });
    alexLib.coolFunction(function (result) {
      /* do stuff with result */
    });
    
  • 或者我可以将错误作为错误事件发出,这似乎更符合您的要求

    var EventEmitter = require('events').EventEmitter;
    exports.eventEmitter = new EventEmitter();
    exports.coolFunction = function (callback) {
      collection.update({ a : 2 }, { $set: { b : 1 } }, function (err, result) {
        if (err) { exports.eventEmitter.emit('error', err); return; }
        callback(result);
      });
    };
    
    然后有人可以像这样使用我的事件样式API:

    var alexLib = require('alexLibExample');
    alexLib.coolFunction(function (err, result) {
      if (err) { /* consumer handles error how they want to in their app */ }
      /* all is good, no errors, continue normally */
    });
    
    var alexLib = require('alexLibExample');
    alexLib.coolFunction().then(function (result) {
      /* do stuff with result */
    }).catch(function (err) {
      /* handle error how user chooses in their app */
    });
    
    var alexLib = require('alexLibExample');
    alexLib.eventEmitter.on('error', function (err) {
      /* user handles error how they choose */
    });
    alexLib.coolFunction(function (result) {
      /* do stuff with result */
    });
    
    API的事件样式通常与回调样式相结合。这意味着它们仍然将错误传递给回调函数,这是大多数用户在传递回调时所期望的。然后,它们还发出一个错误事件,作为用户可以订阅的一种全局错误处理程序。我知道这就是工作方式。我可以捕获单个API调用上的错误,也可以设置错误事件处理程序并在那里处理所有错误

    var EventEmitter = require('events').EventEmitter;
    exports.eventEmitter = new EventEmitter();
    exports.coolFunction = function (callback) {
      collection.update({ a : 2 }, { $set: { b : 1 } }, function (err, result) {
        if (err) { exports.eventEmitter.emit('error', err); callback(err); return; }
        callback(null, result);
      });
    };
    
    然后用户在处理错误方面有一定的灵活性

    var alexLib = require('alexLibExample');
    alexLib.eventEmitter.on('error', function (err) {
      /* handle all errors here */
    });
    alexLib.coolFunction(function (err, result) {
      if (err) { return; }
      /* do stuff with result */
    });
    alexLib.coolFunction2(function (err, result) {
      if (err) { /* maybe I have special error handling for this specific call. I can do that here */ }
      /* do stuff with result */
    });
    
  • 如果你真的想得到花式,你可以结合这三种风格

    var EventEmitter = require('events').EventEmitter;
    var Promise = require('bluebird');
    exports.eventEmitter = new EventEmitter();
    exports.coolFunction = function (callback) {
      return new Promise(function (resolve, reject) {
        collection.update({ a : 2 }, { $set: { b : 1 } }, function(err, result) {
          if (err) {
            if (callback) { callback(err); }
            reject(err);
            exports.eventEmitter.emit('error', err);
          }
          if (callback) { callback(err, result); }
          resolve(result);
        });
      });
    };
    
    然后,有人可以随意使用我的API

    var alexLib = require('alexLibExample');
    alexLib.eventEmitter.on('error', function (err) {
      /* handle all errors here */
    });
    alexLib.coolFunction(function (err, result) {
      if (err) {
        /* handle this specific error how user chooses */
      }
      /* do stuff with result */
    });
    
    // or
    
    alexLib.coolFunction().then(function (result) {
      /* do stuff with result */
    }).catch(function (err) {
      /* handle any errors in this promise chain */
    });
    

    您是从API返回承诺还是回调?你能给我们一些代码示例吗?其他人如何使用您的API?当他们这样做时,他们对您的API的调用如何最终成为对MongoDB驱动程序API的调用?显示一些代码,我可能会告诉您如何最好地围绕您想要的方式传输错误。完成,感谢您的查看!您是从API返回承诺还是回调?你能给我们一些代码示例吗?其他人如何使用您的API?当他们这样做时,他们对您的API的调用如何最终成为对MongoDB驱动程序API的调用?显示一些代码,我可能会告诉您如何最好地围绕您想要的方式传输错误。完成,感谢您的查看!谢谢你的广泛回答,但我恐怕它不能回答我的问题。我不包装驱动程序API,而是直接向客户机公开它。我要找的是wa