Skip to content
This repository has been archived by the owner on Feb 26, 2024. It is now read-only.

Commit

Permalink
Fixed Ganache loading forever being stuck because project details loa…
Browse files Browse the repository at this point in the history
…der never resolves/rejects

The project loader is performed using a child spawn that should resolved
or rejects at some point. However, it seems that in some cases (when some
dependencies of the truffle project are missing), the child spawn will
issue an 'exit` event without ever entering the 'error` event.

This is problematic because since this is not trapped properly, the actual
Ganache dependency that is waiting for project loading to happen never
resolves and the Ganache UI is loading forever being stuck in this loop.

To resolves that, the 'exit' signal is now catched as well as the standard
error output of the process. When the child process exits with a bad
error code and as now received the `error` event, a message is now
forwarded within an `Error` object and the standard error output is present
in there.

This removes the infinite loop in Ganache and shows the actual standard
error in the process.

Caveats, this renders as 'Oups this is a bug' dialog in Ganache while it's
really a problem with the truffle project not being configured correctly.
I think it's good enough as a first solving, but this could be improved
later on be provided a different UI saying the project is misconfigured
or something like this.
  • Loading branch information
Matthieu Vachon committed Aug 4, 2019
1 parent efc2365 commit 5ac0f46
Showing 1 changed file with 28 additions and 2 deletions.
30 changes: 28 additions & 2 deletions src/truffle-integration/projectDetails.js
Original file line number Diff line number Diff line change
Expand Up @@ -134,8 +134,13 @@ async function get(projectFile, isRetry = false) {
stdio: ["pipe", "pipe", "pipe", "ipc"],
cwd: configFileDirectory,
};

const child = child_process.spawn("node", args, options);

let receivedErrorEvent = false;
child.on("error", async error => {
receivedErrorEvent = true;

const response = {
name: name,
configFile: projectFile,
Expand All @@ -161,9 +166,30 @@ async function get(projectFile, isRetry = false) {
}
resolve(response);
});
child.stderr.on("data", () => {
// we ignore stderr on purpose, as some truffle configs may be writing to it (via console.error, etc).

child.on("exit", code => {
if (code != 0 && !receivedErrorEvent) {
const messageLines = [
"An error occurred while running the project loader script",
`for project file ${projectFile} in ${configFileDirectory} folder.`,
"",
"Here the standard error ouput of the project loader script:",
"",
stdErrLines.join("\n"),
];

throw new Error(messageLines.join("\n"));
}
});

const stdErrLines = [];
child.stderr.on("data", message => {
// we know stderr is not fully reliable, as some truffle configs may be writing to it (via console.error, etc).
// however, we still catch in case we exit straight via the `on('exit')` to display a meaningful message
// to the user.
stdErrLines.push(message);
});

child.on("message", async output => {
if (output.error) {
return resolve({
Expand Down

0 comments on commit 5ac0f46

Please sign in to comment.