From cb804b00c4c05358c706a7db0ee73bf451fad107 Mon Sep 17 00:00:00 2001
From: RahulGautamSingh <rahultesnik@gmail.com>
Date: Tue, 4 Jun 2024 22:48:26 +0545
Subject: [PATCH] fix(platform/gitlab): handle assignee id not found (#29307)

Co-authored-by: Sebastian Poxhofer <secustor@users.noreply.github.com>
---
 lib/modules/platform/gitlab/http.ts       | 13 +++++++--
 lib/modules/platform/gitlab/index.spec.ts | 33 +++++++++++++++++++++++
 lib/modules/platform/gitlab/index.ts      |  8 +++++-
 3 files changed, 51 insertions(+), 3 deletions(-)

diff --git a/lib/modules/platform/gitlab/http.ts b/lib/modules/platform/gitlab/http.ts
index 54a5555be8..51f6fc401f 100644
--- a/lib/modules/platform/gitlab/http.ts
+++ b/lib/modules/platform/gitlab/http.ts
@@ -1,3 +1,4 @@
+import is from '@sindresorhus/is';
 import { logger } from '../../../logger';
 import { GitlabHttp } from '../../../util/http/gitlab';
 import type { GitLabUser, GitlabUserStatus } from './types';
@@ -5,9 +6,17 @@ import type { GitLabUser, GitlabUserStatus } from './types';
 export const gitlabApi = new GitlabHttp();
 
 export async function getUserID(username: string): Promise<number> {
-  return (
+  const userInfo = (
     await gitlabApi.getJson<{ id: number }[]>(`users?username=${username}`)
-  ).body[0].id;
+  ).body;
+
+  if (is.emptyArray(userInfo)) {
+    throw new Error(
+      `User ID for the username: ${username} could not be found.`,
+    );
+  }
+
+  return userInfo[0].id;
 }
 
 async function getMembers(group: string): Promise<GitLabUser[]> {
diff --git a/lib/modules/platform/gitlab/index.spec.ts b/lib/modules/platform/gitlab/index.spec.ts
index 8366103aae..3878f49d62 100644
--- a/lib/modules/platform/gitlab/index.spec.ts
+++ b/lib/modules/platform/gitlab/index.spec.ts
@@ -1316,11 +1316,44 @@ describe('modules/platform/gitlab/index', () => {
       httpMock
         .scope(gitlabApiHost)
         .get('/api/v4/users?username=someuser')
+        .replyWithError('some error')
+        .get('/api/v4/users?username=someotheruser')
+        .reply(200, [{ id: 124 }])
+        .put('/api/v4/projects/undefined/merge_requests/42?assignee_ids[]=124')
         .replyWithError('some error');
       await expect(
         gitlab.addAssignees(42, ['someuser', 'someotheruser']),
       ).toResolve();
     });
+
+    it('should log message for each assignee that could not be found', async () => {
+      httpMock
+        .scope(gitlabApiHost)
+        .get('/api/v4/users?username=someuser')
+        .reply(304, [])
+        .get('/api/v4/users?username=someotheruser')
+        .reply(200, [{ id: 124 }])
+        .put('/api/v4/projects/undefined/merge_requests/42?assignee_ids[]=124')
+        .reply(200);
+      await expect(
+        gitlab.addAssignees(42, ['someuser', 'someotheruser']),
+      ).toResolve();
+      expect(logger.warn).toHaveBeenCalledWith(
+        {
+          assignee: 'someuser',
+        },
+        'Failed to add assignee - could not get ID',
+      );
+      expect(logger.debug).toHaveBeenCalledWith(
+        {
+          assignee: 'someuser',
+          err: new Error(
+            'User ID for the username: someuser could not be found.',
+          ),
+        },
+        'getUserID() error',
+      );
+    });
   });
 
   describe('addReviewers(iid, reviewers)', () => {
diff --git a/lib/modules/platform/gitlab/index.ts b/lib/modules/platform/gitlab/index.ts
index 0988ad0bb8..90eccc206c 100644
--- a/lib/modules/platform/gitlab/index.ts
+++ b/lib/modules/platform/gitlab/index.ts
@@ -1217,7 +1217,13 @@ export async function addAssignees(
     logger.debug(`Adding assignees '${assignees.join(', ')}' to #${iid}`);
     const assigneeIds: number[] = [];
     for (const assignee of assignees) {
-      assigneeIds.push(await getUserID(assignee));
+      try {
+        const userId = await getUserID(assignee);
+        assigneeIds.push(userId);
+      } catch (err) {
+        logger.debug({ assignee, err }, 'getUserID() error');
+        logger.warn({ assignee }, 'Failed to add assignee - could not get ID');
+      }
     }
     const url = `projects/${
       config.repository
-- 
GitLab