117 lines
3 KiB
JavaScript
117 lines
3 KiB
JavaScript
|
const { runHandler, isMutating } = require('../../../server/mutators');
|
||
|
const ipc = require('node-ipc');
|
||
|
const { captureException } = require('../../exceptions');
|
||
|
|
||
|
function coerceError(error) {
|
||
|
if (error.type && error.type === 'APIError') {
|
||
|
return error;
|
||
|
}
|
||
|
|
||
|
return { type: 'InternalError', message: error.message };
|
||
|
}
|
||
|
|
||
|
function init(socketName, handlers) {
|
||
|
ipc.config.id = socketName;
|
||
|
ipc.config.silent = true;
|
||
|
|
||
|
ipc.serve(() => {
|
||
|
ipc.server.on('message', (data, socket) => {
|
||
|
let msg = JSON.parse(data);
|
||
|
let { id, name, args, undoTag, catchErrors } = msg;
|
||
|
|
||
|
if (handlers[name]) {
|
||
|
runHandler(handlers[name], args, { undoTag, name }).then(
|
||
|
result => {
|
||
|
if (catchErrors) {
|
||
|
result = { data: result, error: null };
|
||
|
}
|
||
|
|
||
|
ipc.server.emit(
|
||
|
socket,
|
||
|
'message',
|
||
|
JSON.stringify({
|
||
|
type: 'reply',
|
||
|
id,
|
||
|
result,
|
||
|
mutated:
|
||
|
isMutating(handlers[name]) &&
|
||
|
name !== 'undo' &&
|
||
|
name !== 'redo',
|
||
|
undoTag
|
||
|
})
|
||
|
);
|
||
|
},
|
||
|
nativeError => {
|
||
|
let error = coerceError(nativeError);
|
||
|
|
||
|
if (name.startsWith('api/')) {
|
||
|
// The API is newer and does automatically forward
|
||
|
// errors
|
||
|
ipc.server.emit(
|
||
|
socket,
|
||
|
'message',
|
||
|
JSON.stringify({ type: 'reply', id, error })
|
||
|
);
|
||
|
} else if (catchErrors) {
|
||
|
ipc.server.emit(
|
||
|
socket,
|
||
|
'message',
|
||
|
JSON.stringify({
|
||
|
type: 'reply',
|
||
|
id,
|
||
|
result: { error, data: null }
|
||
|
})
|
||
|
);
|
||
|
} else {
|
||
|
ipc.server.emit(
|
||
|
socket,
|
||
|
'message',
|
||
|
JSON.stringify({ type: 'error', id })
|
||
|
);
|
||
|
}
|
||
|
|
||
|
if (error.type === 'InternalError' && name !== 'api/load-budget') {
|
||
|
captureException(nativeError);
|
||
|
}
|
||
|
|
||
|
if (!catchErrors) {
|
||
|
// Notify the frontend that something bad happend
|
||
|
send('server-error');
|
||
|
}
|
||
|
}
|
||
|
);
|
||
|
} else {
|
||
|
console.warn('Unknown method: ' + name);
|
||
|
captureException(new Error('Unknown server method: ' + name));
|
||
|
ipc.server.emit(
|
||
|
socket,
|
||
|
'message',
|
||
|
JSON.stringify({
|
||
|
type: 'reply',
|
||
|
id,
|
||
|
result: null,
|
||
|
error: { type: 'APIError', message: 'Unknown method: ' + name }
|
||
|
})
|
||
|
);
|
||
|
}
|
||
|
});
|
||
|
});
|
||
|
|
||
|
ipc.server.start();
|
||
|
}
|
||
|
|
||
|
function getNumClients() {
|
||
|
return ipc.server.sockets.length;
|
||
|
}
|
||
|
|
||
|
function send(name, args) {
|
||
|
if (ipc.server) {
|
||
|
ipc.server.broadcast(
|
||
|
'message',
|
||
|
JSON.stringify({ type: 'push', name, args })
|
||
|
);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
module.exports = { init, send, getNumClients };
|