Proper error code and message when failing (#295)

Prior to this, the CLI would exit with UnhandledPromiseRejectionWarning
and a full stack trace when an error occurred.

With this change, set an error code indicating failure and only display
the error message by default. The stack trace is printed with --verbose.

Furthermore, the loud-rejection handler is registered to fail properly
if any rejected promises snuck past our handling.
diff --git a/bin/cordova b/bin/cordova
index bab9b88..b91d9dd 100755
--- a/bin/cordova
+++ b/bin/cordova
@@ -37,6 +37,21 @@
 }
 
 addTs('start');
-var cli = require('../src/cli');
-cli(process.argv);
+
+require('loud-rejection/register');
+const util = require('util');
+const { events, CordovaError } = require('cordova-common');
+const cli = require('../src/cli');
+
+cli(process.argv).catch(err => {
+    if (!(err instanceof Error)) {
+        throw new CordovaError('Promise rejected with non-error: ' + util.inspect(err));
+    }
+    process.exitCode = err.code || 1;
+
+    // We cannot emit an error event here, as that would cause another error
+    console.error(err.message);
+    events.emit('verbose', err.stack);
+});
+
 addTs('end');
diff --git a/package.json b/package.json
index e02cb2c..f0df101 100644
--- a/package.json
+++ b/package.json
@@ -35,6 +35,7 @@
     "cordova-lib": "8.0.0",
     "editor": "1.0.0",
     "insight": "0.8.4",
+    "loud-rejection": "^1.6.0",
     "nopt": "3.0.1",
     "update-notifier": "0.5.0"
   },
diff --git a/src/cli.js b/src/cli.js
index 7791b30..2bef360 100644
--- a/src/cli.js
+++ b/src/cli.js
@@ -165,7 +165,7 @@
         });
     }
 
-    Promise.resolve().then(function () {
+    return Promise.resolve().then(function () {
         /**
          * Skip telemetry prompt if:
          * - CI environment variable is present