diff --git a/.changeset/fair-dolphins-relate.md b/.changeset/fair-dolphins-relate.md new file mode 100644 index 0000000000..85bc517a8d --- /dev/null +++ b/.changeset/fair-dolphins-relate.md @@ -0,0 +1,7 @@ +--- +'@backstage/plugin-catalog-backend-module-msgraph': minor +--- + +Handle error gracefully if failure occurs while loading photos using Microsoft Graph API. + +This includes a breaking change: you now have to pass the `options` object to `readMicrosoftGraphUsers` and `readMicrosoftGraphOrg`. diff --git a/plugins/catalog-backend-module-msgraph/api-report.md b/plugins/catalog-backend-module-msgraph/api-report.md index 702601b469..f1e7e22c35 100644 --- a/plugins/catalog-backend-module-msgraph/api-report.md +++ b/plugins/catalog-backend-module-msgraph/api-report.md @@ -103,10 +103,11 @@ export type OrganizationTransformer = (organization: MicrosoftGraph.Organization export function readMicrosoftGraphConfig(config: Config): MicrosoftGraphProviderConfig[]; // @public (undocumented) -export function readMicrosoftGraphOrg(client: MicrosoftGraphClient, tenantId: string, options?: { +export function readMicrosoftGraphOrg(client: MicrosoftGraphClient, tenantId: string, options: { userFilter?: string; groupFilter?: string; groupTransformer?: GroupTransformer; + logger: Logger; }): Promise<{ users: UserEntity[]; groups: GroupEntity[]; diff --git a/plugins/catalog-backend-module-msgraph/package.json b/plugins/catalog-backend-module-msgraph/package.json index f37b954706..417ef90c6e 100644 --- a/plugins/catalog-backend-module-msgraph/package.json +++ b/plugins/catalog-backend-module-msgraph/package.json @@ -40,6 +40,7 @@ "qs": "^6.9.4" }, "devDependencies": { + "@backstage/backend-common": "^0.8.3", "@backstage/cli": "^0.7.2", "@backstage/test-utils": "^0.1.14", "@types/lodash": "^4.14.151", diff --git a/plugins/catalog-backend-module-msgraph/src/microsoftGraph/read.test.ts b/plugins/catalog-backend-module-msgraph/src/microsoftGraph/read.test.ts index b1179c20df..929d01e128 100644 --- a/plugins/catalog-backend-module-msgraph/src/microsoftGraph/read.test.ts +++ b/plugins/catalog-backend-module-msgraph/src/microsoftGraph/read.test.ts @@ -23,6 +23,7 @@ import { readMicrosoftGraphUsers, resolveRelations, } from './read'; +import { getVoidLogger } from '@backstage/backend-common'; function user(data: Partial): UserEntity { return merge( @@ -84,6 +85,7 @@ describe('read microsoft graph', () => { const { users } = await readMicrosoftGraphUsers(client, { userFilter: 'accountEnabled eq true', + logger: getVoidLogger(), }); expect(users).toEqual([ diff --git a/plugins/catalog-backend-module-msgraph/src/microsoftGraph/read.ts b/plugins/catalog-backend-module-msgraph/src/microsoftGraph/read.ts index 70c403d0b7..a9e2465ad7 100644 --- a/plugins/catalog-backend-module-msgraph/src/microsoftGraph/read.ts +++ b/plugins/catalog-backend-module-msgraph/src/microsoftGraph/read.ts @@ -33,6 +33,7 @@ import { OrganizationTransformer, UserTransformer, } from './types'; +import { Logger } from 'winston'; export async function defaultUserTransformer( user: MicrosoftGraph.User, @@ -75,7 +76,11 @@ export async function defaultUserTransformer( export async function readMicrosoftGraphUsers( client: MicrosoftGraphClient, - options?: { userFilter?: string; transformer?: UserTransformer }, + options: { + userFilter?: string; + transformer?: UserTransformer; + logger: Logger; + }, ): Promise<{ users: UserEntity[]; // With all relations empty }> { @@ -86,17 +91,22 @@ export async function readMicrosoftGraphUsers( const promises: Promise[] = []; for await (const user of client.getUsers({ - filter: options?.userFilter, + filter: options.userFilter, })) { // Process all users in parallel, otherwise it can take quite some time promises.push( limiter(async () => { - const userPhoto = await client.getUserPhotoWithSizeLimit( - user.id!, - // We are limiting the photo size, as users with full resolution photos - // can make the Backstage API slow - 120, - ); + let userPhoto; + try { + userPhoto = await client.getUserPhotoWithSizeLimit( + user.id!, + // We are limiting the photo size, as users with full resolution photos + // can make the Backstage API slow + 120, + ); + } catch (e) { + options.logger.warn(`Unable to load photo for ${user.id}`); + } const entity = await transformer(user, userPhoto); @@ -371,14 +381,16 @@ export function resolveRelations( export async function readMicrosoftGraphOrg( client: MicrosoftGraphClient, tenantId: string, - options?: { + options: { userFilter?: string; groupFilter?: string; groupTransformer?: GroupTransformer; + logger: Logger; }, ): Promise<{ users: UserEntity[]; groups: GroupEntity[] }> { const { users } = await readMicrosoftGraphUsers(client, { - userFilter: options?.userFilter, + userFilter: options.userFilter, + logger: options.logger, }); const { groups, diff --git a/plugins/catalog-backend-module-msgraph/src/processors/MicrosoftGraphOrgReaderProcessor.ts b/plugins/catalog-backend-module-msgraph/src/processors/MicrosoftGraphOrgReaderProcessor.ts index d86584a9fd..88240db618 100644 --- a/plugins/catalog-backend-module-msgraph/src/processors/MicrosoftGraphOrgReaderProcessor.ts +++ b/plugins/catalog-backend-module-msgraph/src/processors/MicrosoftGraphOrgReaderProcessor.ts @@ -90,6 +90,7 @@ export class MicrosoftGraphOrgReaderProcessor implements CatalogProcessor { userFilter: provider.userFilter, groupFilter: provider.groupFilter, groupTransformer: this.groupTransformer, + logger: this.logger, }, );