mirror of
https://github.com/balena-io/etcher.git
synced 2025-04-24 07:17:18 +00:00
fix(GUI): terminate IPC server on any errors (#872)
If the child process (e.g: writer proxy, or CLI) emits either an error, or an invalid output, the error will be emitted to the GUI, which will report it to the state machine, however the IPC server will keep receiving further messages, which will be passed to the GUI, which will keep trying to update the state, in which case Redux will rightfully complain that we can't update the flashing state if there is no flash in process. As a solution, we make sure the IPC server is terminated on every possible error code flow, and to do this effectively, we needed to manually destroy every connected socket before actually closing the server. Change-Type: patch Changelog-Entry: Fix "Can't set the flashing state when not flashing" error. Signed-off-by: Juan Cruz Viotti <jviotti@openmailbox.org>
This commit is contained in:
parent
9b6cd5c81c
commit
938fa71d50
@ -17,6 +17,7 @@
|
||||
'use strict';
|
||||
|
||||
const EventEmitter = require('events').EventEmitter;
|
||||
const _ = require('lodash');
|
||||
const childProcess = require('child_process');
|
||||
const ipc = require('node-ipc');
|
||||
const rendererUtils = require('./renderer-utils');
|
||||
@ -75,20 +76,39 @@ exports.write = (image, drive, options) => {
|
||||
ipc.config.silent = true;
|
||||
ipc.serve();
|
||||
|
||||
ipc.server.on('error', (error) => {
|
||||
emitter.emit('error', error);
|
||||
});
|
||||
const terminateServer = () => {
|
||||
|
||||
// Turns out we need to destroy all sockets for
|
||||
// the server to actually close. Otherwise, it
|
||||
// just stops receiving any further connections,
|
||||
// but remains open if there are active ones.
|
||||
_.each(ipc.server.sockets, (socket) => {
|
||||
socket.destroy();
|
||||
});
|
||||
|
||||
ipc.server.stop();
|
||||
};
|
||||
|
||||
const emitError = (error) => {
|
||||
terminateServer();
|
||||
emitter.emit('error', error);
|
||||
};
|
||||
|
||||
ipc.server.on('error', emitError);
|
||||
ipc.server.on('message', (data) => {
|
||||
let message;
|
||||
try {
|
||||
message = JSON.parse(data);
|
||||
} catch (error) {
|
||||
return emitter.emit('error', new Error(`Invalid message: ${data}`));
|
||||
error.description = `${data}, ${error.message}`;
|
||||
error.message = 'Invalid message from the writer process';
|
||||
return emitError(error);
|
||||
}
|
||||
|
||||
if (!message.command || !message.data) {
|
||||
return emitter.emit('error', new Error(`Invalid message: ${data}`));
|
||||
const error = new Error('Invalid message from the writer process');
|
||||
error.description = `No command or data: ${data}`;
|
||||
return emitError(error);
|
||||
}
|
||||
|
||||
// The error object is decomposed by the CLI for serialisation
|
||||
@ -99,7 +119,7 @@ exports.write = (image, drive, options) => {
|
||||
error.code = message.data.code;
|
||||
error.description = message.data.description;
|
||||
error.stack = message.data.stacktrace;
|
||||
return emitter.emit('error', error);
|
||||
return emitError(error);
|
||||
}
|
||||
|
||||
emitter.emit(message.command, message.data);
|
||||
@ -116,20 +136,17 @@ exports.write = (image, drive, options) => {
|
||||
});
|
||||
|
||||
child.stderr.on('data', (data) => {
|
||||
emitter.emit('error', new Error(data.toString()));
|
||||
emitError(new Error(data.toString()));
|
||||
|
||||
// This function causes the `close` event to be emitted
|
||||
child.kill();
|
||||
|
||||
});
|
||||
|
||||
child.on('error', (error) => {
|
||||
ipc.server.stop();
|
||||
emitter.emit('error', error);
|
||||
});
|
||||
child.on('error', emitError);
|
||||
|
||||
child.on('close', (code) => {
|
||||
ipc.server.stop();
|
||||
terminateServer();
|
||||
|
||||
if (code === EXIT_CODES.CANCELLED) {
|
||||
return emitter.emit('done', {
|
||||
@ -138,7 +155,7 @@ exports.write = (image, drive, options) => {
|
||||
}
|
||||
|
||||
if (code !== EXIT_CODES.SUCCESS && code !== EXIT_CODES.VALIDATION_ERROR) {
|
||||
return emitter.emit('error', new Error(`Child process exitted with error code: ${code}`));
|
||||
return emitError(new Error(`Child process exited with error code: ${code}`));
|
||||
}
|
||||
});
|
||||
});
|
||||
|
Loading…
x
Reference in New Issue
Block a user