From d453f6cce746dc40a4041cba58c0df7faeb34a7d Mon Sep 17 00:00:00 2001
From: Rhys Arkins <rhys@keylocation.sg>
Date: Fri, 2 Jun 2017 08:06:44 +0200
Subject: [PATCH] Add try/catch around yarn.lock generation (#225)

* Add try/catch around yarn.lock calls

* Improve test structure
---
 lib/workers/branch.js       | 34 ++++++++++++++++++++++------------
 test/workers/branch.spec.js | 37 +++++++++++++++++++++++++++++++++++++
 2 files changed, 59 insertions(+), 12 deletions(-)

diff --git a/lib/workers/branch.js b/lib/workers/branch.js
index 509074048b..52a48d5778 100644
--- a/lib/workers/branch.js
+++ b/lib/workers/branch.js
@@ -68,9 +68,14 @@ async function ensureBranch(upgrades) {
   const commitFiles = [];
   for (const upgrade of upgrades) {
     if (upgrade.upgradeType === 'maintainYarnLock') {
-      const newYarnLock = await yarnHelper.maintainLockFile(upgrade);
-      if (newYarnLock) {
-        commitFiles.push(newYarnLock);
+      try {
+        const newYarnLock = await yarnHelper.maintainLockFile(upgrade);
+        if (newYarnLock) {
+          commitFiles.push(newYarnLock);
+        }
+      } catch (err) {
+        logger.debug(err);
+        throw new Error('Could not maintain yarn.lock file');
       }
     } else {
       // See if this is the first time editing this file
@@ -106,15 +111,20 @@ async function ensureBranch(upgrades) {
         name: packageFile,
         contents: packageFiles[packageFile],
       });
-      const yarnLockFile = await yarnHelper.getLockFile(
-        packageFile,
-        packageFiles[packageFile],
-        api
-      );
-      if (yarnLockFile) {
-        // Add new yarn.lock file too
-        logger.debug(`Adding ${yarnLockFile.name}`);
-        commitFiles.push(yarnLockFile);
+      try {
+        const yarnLockFile = await yarnHelper.getLockFile(
+          packageFile,
+          packageFiles[packageFile],
+          api
+        );
+        if (yarnLockFile) {
+          // Add new yarn.lock file too
+          logger.debug(`Adding ${yarnLockFile.name}`);
+          commitFiles.push(yarnLockFile);
+        }
+      } catch (err) {
+        logger.debug(err);
+        throw new Error('Could not generate new yarn.lock file');
       }
     }
   }
diff --git a/test/workers/branch.spec.js b/test/workers/branch.spec.js
index 5fd76ec25c..04179550d1 100644
--- a/test/workers/branch.spec.js
+++ b/test/workers/branch.spec.js
@@ -135,6 +135,24 @@ describe('workers/branch', () => {
       expect(yarnHelper.getLockFile.mock.calls.length).toBe(1);
       expect(config.api.commitFilesToBranch.mock.calls[0][1].length).toBe(2);
     });
+    it('throws an error if no yarn lock generation possible', async () => {
+      branchWorker.getParentBranch.mockReturnValueOnce('dummy branch');
+      yarnHelper.getLockFile.mockImplementationOnce(() => {
+        throw new Error('yarn not found');
+      });
+      packageJsonHelper.setNewValue.mockReturnValueOnce('new content');
+      let err;
+      try {
+        await branchWorker.ensureBranch([config]);
+      } catch (e) {
+        err = e;
+      }
+      expect(err.message).toBe('Could not generate new yarn.lock file');
+      expect(branchWorker.getParentBranch.mock.calls.length).toBe(1);
+      expect(packageJsonHelper.setNewValue.mock.calls.length).toBe(1);
+      expect(yarnHelper.getLockFile.mock.calls.length).toBe(1);
+      expect(config.api.commitFilesToBranch.mock.calls.length).toBe(0);
+    });
     it('maintains lock files if needing updates', async () => {
       branchWorker.getParentBranch.mockReturnValueOnce('dummy branch');
       yarnHelper.maintainLockFile.mockReturnValueOnce('non null response');
@@ -156,5 +174,24 @@ describe('workers/branch', () => {
       expect(yarnHelper.maintainLockFile.mock.calls.length).toBe(1);
       expect(config.api.commitFilesToBranch.mock.calls.length).toBe(0);
     });
+    it('throws error if cannot maintain yarn.lock file', async () => {
+      branchWorker.getParentBranch.mockReturnValueOnce('dummy branch');
+      config.upgradeType = 'maintainYarnLock';
+      yarnHelper.maintainLockFile.mockImplementationOnce(() => {
+        throw new Error('yarn not found');
+      });
+      let err;
+      try {
+        await branchWorker.ensureBranch([config]);
+      } catch (e) {
+        err = e;
+      }
+      expect(err.message).toBe('Could not maintain yarn.lock file');
+      expect(branchWorker.getParentBranch.mock.calls.length).toBe(1);
+      expect(packageJsonHelper.setNewValue.mock.calls.length).toBe(0);
+      expect(yarnHelper.getLockFile.mock.calls.length).toBe(0);
+      expect(yarnHelper.maintainLockFile.mock.calls.length).toBe(1);
+      expect(config.api.commitFilesToBranch.mock.calls.length).toBe(0);
+    });
   });
 });
-- 
GitLab