如何将错误对象传递给socket.io回调

时间:2014-01-04 01:20:08

标签: javascript node.js socket.io

我正在使用socket.io

的回调

客户代码:

socket.emit('someEvent', {data:1}, function(err, result) {
    console.log(err.message); 
});

服务器代码:

socket.on('someEvent', function(data, callback) {
    callback(new Error('testing error'));
});

使用上面的代码,客户端总是打印出undefined。如果我将服务器端代码更改为以下内容,则可以看到错误消息。

socket.on('someEvent', function(data, callback) {
    callback({message:'testing error'});
});

我可以将自己的自定义对象传递给客户端,只是不是错误对象。有什么想法吗?

3 个答案:

答案 0 :(得分:10)

socket.io数据被序列化为JSON,它只能表示普通对象。您需要将任何错误序列化为可识别的普通对象格式,或者让Socket.IO的标准序列化执行其操作(这将导致Error实例的纯空对象。

答案 1 :(得分:0)

我还认为Socket.IO似乎没有为以有意义的方式传递Error对象提供明确的内置支持,这很奇怪。

如果要在Socket.IO回调中正确地分类错误对象,可以定义这样的方法,以指定如何处理错误消息.toJSON的序列化:

if (!('toJSON' in Error.prototype)) {
    Object.defineProperty(Error.prototype, 'toJSON', {
    value: function () {
      let result = {}
      Object.getOwnPropertyNames(this).forEach((key) => {
        if (key === 'stack') return
        result[key] = this[key];
      }, this)
      return result
    },
    configurable: true,
    writable: true
  })
}

如果要从服务器发送消息,则需要在服务器上定义消息,如果从客户端向服务器抛出错误,则需要在客户端上定义它。

注意:在此示例中,它在向客户端返回错误时剥离了“stack”属性(以避免将内部暴露给客户端),但这可能值得留下,至少对于开发模式而言。

更新:使用ES6

可以轻松实现

改编自我最近写的一篇博文:

https://medium.com/@iaincollins/error-handling-in-javascript-a6172ccdf9af

我很高兴用ES6说这更容易/更清洁。

如果您定义类扩展错误,请执行以下操作:

class ValidationError extends Error {
  constructor(message) {
    super(message)
    this.name = 'ValidationError'
    this.message = message
  }

  toJSON() {
    return {
      error: {
        name: this.name,
        message: this.message,
        stacktrace: this.stack
      }
    }
  }
}

而不是传递回来的对象:

{ name: 'ValidationError' }

现在看起来像这样:

{ 
  error: {
    name: 'ValidationError',
    message: 'A validation error',
    stacktrace: '…'
  }
}

您可以通过这样做看到期望:

console.log(JSON.stringify(new ValidationError('A validation error'))

答案 2 :(得分:0)

这里有一个路由器功能,可用于普通错误对象。如果您很害羞,则可能要删除堆栈变量。

socket.on('api', async (method, args, callback) {
  try {
    const result = await api[method](...args)
    callback(null, result)
  } catch (error) {
    const { name, message, stack } = error
    callback(error.toJSON ? error : { name, message, stack })
  }
})