How To Pass Error Object To Socket.io Callback
Solution 1:
socket.io
data is serialized as JSON
, which can only represent plain objects. You will need to serialize any errors into a recognizable plain-object format, or let Socket.IO's standard serialization do its thing (which will result in a plain empty object for Error
instances.
Solution 2:
I also think it's odd that Socket.IO doesn't seem to provide explicit built in support for passing Error objects in a meaningful way.
If you want to have Error objects seralized correctly in Socket.IO callbacks you can define a method like this to specify how serialization with .toJSON
for Error messages should be handled:
if (!('toJSON'inError.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
})
}
If you are throwing messages from the server you will want to define this on the server, and if throwing errors from a client to the server you will need to define it on the client too.
Note: In this example it strips the 'stack' property when returning errors to the client (to avoid exposing internals to a client), but this may be something worth leaving in, at least for development mode.
Update: This is a lot easier with ES6
Adapted from a blog post I wrote recently on this:
https://medium.com/@iaincollins/error-handling-in-javascript-a6172ccdf9af
I'm happy to say this easier/cleaner with ES6.
If you define your class extending Error like this:
classValidationErrorextendsError {
constructor(message) {
super(message)
this.name = 'ValidationError'this.message = message
}
toJSON() {
return {
error: {
name: this.name,
message: this.message,
stacktrace: this.stack
}
}
}
}
Instead of this being the object that gets passed back:
{ name: 'ValidationError' }
It now looks something like this:
{
error: {
name: 'ValidationError',
message: 'A validation error',
stacktrace: '…'
}
}
You can see what to expect by doing this:
console.log(JSON.stringify(newValidationError('A validation error'))
Solution 3:
Here's a little router function that works with plain error objects. You might want to remove the stack variable if you're shy.
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 })
}
})
Post a Comment for "How To Pass Error Object To Socket.io Callback"