From f93927af632b49eee46c12b51aaafaf605b8908c Mon Sep 17 00:00:00 2001
From: Gabriel-Ladzaretti
 <97394622+Gabriel-Ladzaretti@users.noreply.github.com>
Date: Tue, 23 Aug 2022 07:22:32 +0300
Subject: [PATCH] refactor(repo/cache): handle data parsing inside repository
 base class (#17346)

Co-authored-by: Michael Kriese <michael.kriese@visualon.de>
---
 lib/util/cache/repository/impl/base.ts       | 10 +++++++++-
 lib/util/cache/repository/impl/local.spec.ts |  8 ++++++++
 lib/util/cache/repository/impl/local.ts      |  5 +----
 3 files changed, 18 insertions(+), 5 deletions(-)

diff --git a/lib/util/cache/repository/impl/base.ts b/lib/util/cache/repository/impl/base.ts
index c927974454..c9a21e9a72 100644
--- a/lib/util/cache/repository/impl/base.ts
+++ b/lib/util/cache/repository/impl/base.ts
@@ -1,5 +1,6 @@
 import { promisify } from 'util';
 import zlib from 'zlib';
+import is from '@sindresorhus/is';
 import hasha from 'hasha';
 import { GlobalConfig } from '../../../../config/global';
 import { logger } from '../../../../logger';
@@ -27,7 +28,14 @@ export abstract class RepoCacheBase implements RepoCache {
 
   async load(): Promise<void> {
     try {
-      const oldCache = await this.read();
+      const data = await this.read();
+      if (!is.string(data)) {
+        logger.debug(
+          `RepoCacheBase.load() - expecting data of type 'string' received '${typeof data}' instead - skipping`
+        );
+        return;
+      }
+      const oldCache = JSON.parse(data);
 
       if (isValidRev12(oldCache, this.repository)) {
         const compressed = Buffer.from(oldCache.payload, 'base64');
diff --git a/lib/util/cache/repository/impl/local.spec.ts b/lib/util/cache/repository/impl/local.spec.ts
index a3ab46953c..92baef1f21 100644
--- a/lib/util/cache/repository/impl/local.spec.ts
+++ b/lib/util/cache/repository/impl/local.spec.ts
@@ -35,6 +35,14 @@ describe('util/cache/repository/impl/local', () => {
     expect(localRepoCache.getData()).toBeEmpty();
   });
 
+  it('skip when receives non-string data', async () => {
+    const localRepoCache = CacheFactory.get('some/repo', 'local');
+    await localRepoCache.load(); // readCacheFile is mocked but has no return value set - therefore returns undefined
+    expect(logger.debug).toHaveBeenCalledWith(
+      "RepoCacheBase.load() - expecting data of type 'string' received 'undefined' instead - skipping"
+    );
+  });
+
   it('loads previously stored cache from disk', async () => {
     const data: RepoCacheData = { semanticCommits: 'enabled' };
     const cacheRecord = await createCacheRecord(data);
diff --git a/lib/util/cache/repository/impl/local.ts b/lib/util/cache/repository/impl/local.ts
index b06ac07571..217ea0023a 100644
--- a/lib/util/cache/repository/impl/local.ts
+++ b/lib/util/cache/repository/impl/local.ts
@@ -12,15 +12,12 @@ export class RepoCacheLocal extends RepoCacheBase {
 
   protected async read(): Promise<unknown> {
     const cacheFileName = this.getCacheFileName();
-    let data: unknown;
     try {
-      const rawCache = await readCacheFile(cacheFileName, 'utf8');
-      data = JSON.parse(rawCache);
+      return await readCacheFile(cacheFileName, 'utf8');
     } catch (err) {
       logger.debug({ cacheFileName }, 'Repository local cache not found');
       throw err;
     }
-    return data;
   }
 
   protected async write(data: RepoCacheRecord): Promise<void> {
-- 
GitLab