From d57d6fdc8bade06dc9ee6f5323828864c25da522 Mon Sep 17 00:00:00 2001 From: cgewecke Date: Thu, 19 Sep 2019 18:40:32 -0700 Subject: [PATCH] Pre-empt EADDRINUSE and show useful error. (#407) --- lib/api.js | 6 ++++++ lib/ui.js | 4 ++++ package.json | 1 + test/units/truffle/errors.js | 8 ++++++-- yarn.lock | 15 ++++++++++++++- 5 files changed, 31 insertions(+), 3 deletions(-) diff --git a/lib/api.js b/lib/api.js index 6a4e672..903279b 100644 --- a/lib/api.js +++ b/lib/api.js @@ -5,6 +5,7 @@ const path = require('path'); const istanbul = require('istanbul'); const util = require('util'); const assert = require('assert'); +const detect = require('detect-port'); const ConfigValidator = require('./validator'); const Instrumenter = require('./instrumenter'); @@ -121,6 +122,11 @@ class API { let retry = false; let address = `http://${this.host}:${this.port}`; + // Check for port-in-use + if (await detect(this.port) !== this.port){ + throw new Error(this.ui.generate('server-fail', [this.port])) + } + if(!this.client) this.client = client; // Prefer client from options this.collector = new DataCollector(this.instrumenter.instrumentationData); diff --git a/lib/ui.js b/lib/ui.js index 011d109..e762884 100644 --- a/lib/ui.js +++ b/lib/ui.js @@ -103,6 +103,10 @@ class AppUI extends UI { 'istanbul-fail': `${c.red('Istanbul coverage reports could not be generated. ')}`, 'sources-fail': `${c.red('Cannot locate expected contract sources folder: ')} ${args[0]}`, + + 'server-fail': `${c.red('Port')} ${args[0]} ${c.red('is already in use.\n')}` + + `${c.red('\tRun: "lsof -i" to find the pid of the process using it.\n')}` + + `${c.red('\tRun: "kill -9 " to kill it.\n')}` } return this._format(kinds[kind]) diff --git a/package.json b/package.json index bca3197..ad7cdbd 100644 --- a/package.json +++ b/package.json @@ -28,6 +28,7 @@ "chalk": "^2.4.2", "death": "^1.1.0", "fs-extra": "^8.1.0", + "detect-port": "^1.3.0", "ganache-core-sc": "2.7.0-sc.0", "ghost-testrpc": "^0.0.2", "global-modules": "^2.0.0", diff --git a/test/units/truffle/errors.js b/test/units/truffle/errors.js index 7b56593..2af13f7 100644 --- a/test/units/truffle/errors.js +++ b/test/units/truffle/errors.js @@ -126,7 +126,7 @@ describe('Truffle Plugin: error cases', function() { }); // This case *does* throw an error, but it's uncatch-able; - it.skip('tries to launch with a port already in use', async function(){ + it('tries to launch with a port already in use', async function(){ verify.cleanInitialState(); const server = ganache.server(); @@ -139,7 +139,11 @@ describe('Truffle Plugin: error cases', function() { await plugin(truffleConfig); assert.fail(); } catch(err){ - assert(err.message.includes('EADDRINUSE: address already in use :::8545')) + assert( + err.message.includes('is already in use') && + err.message.includes('lsof'), + `Should error on port-in-use with advice: ${err.message}` + ) } await pify(server.close)(); diff --git a/yarn.lock b/yarn.lock index 8eba17f..5cc76b8 100644 --- a/yarn.lock +++ b/yarn.lock @@ -288,6 +288,11 @@ accepts@~1.3.7: mime-types "~2.1.24" negotiator "0.6.2" +address@^1.0.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/address/-/address-1.1.2.tgz#bf1116c9c758c51b7a933d296b72c221ed9428b6" + integrity sha512-aT6camzM4xEA54YVJYSqxz1kv4IHnQZRtThJJHhUMRExaU5spC7jX5ugSwTaTgJliIgs4VhZOk7htClvQ/LmRA== + aes-js@3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/aes-js/-/aes-js-3.0.0.tgz#e21df10ad6c2053295bcbb8dab40b09dbea87e4d" @@ -1828,7 +1833,7 @@ death@^1.1.0: resolved "https://registry.yarnpkg.com/death/-/death-1.1.0.tgz#01aa9c401edd92750514470b8266390c66c67318" integrity sha1-AaqcQB7dknUFFEcLgmY5DGbGcxg= -debug@2.6.9, debug@^2.2.0, debug@^2.6.8, debug@^2.6.9: +debug@2.6.9, debug@^2.2.0, debug@^2.6.0, debug@^2.6.8, debug@^2.6.9: version "2.6.9" resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== @@ -2029,6 +2034,14 @@ detect-indent@^4.0.0: dependencies: repeating "^2.0.0" +detect-port@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/detect-port/-/detect-port-1.3.0.tgz#d9c40e9accadd4df5cac6a782aefd014d573d1f1" + integrity sha512-E+B1gzkl2gqxt1IhUzwjrxBKRqx1UzC3WLONHinn8S3T6lwV/agVCyitiFOsGJ/eYuEUBvD71MZHy3Pv1G9doQ== + dependencies: + address "^1.0.1" + debug "^2.6.0" + diff@3.5.0: version "3.5.0" resolved "https://registry.yarnpkg.com/diff/-/diff-3.5.0.tgz#800c0dd1e0a8bfbc95835c202ad220fe317e5a12"