我正在使用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'});
});
我可以将自己的自定义对象传递给客户端,只是不是错误对象。有什么想法吗?
答案 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”属性(以避免将内部暴露给客户端),但这可能值得留下,至少对于开发模式而言。
改编自我最近写的一篇博文:
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 })
}
})