Skip to content

Commit 1027f9a

Browse files
committed
Allows partially successful results for the Launchpad.
Shows the error on Launchpad anong with PRs. (#4748, #4492)
1 parent 914781c commit 1027f9a

File tree

5 files changed

+42
-25
lines changed

5 files changed

+42
-25
lines changed

src/plus/integrations/integrationService.ts

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import {
1414
import type { Source } from '../../constants.telemetry';
1515
import { detailToContext, sourceToContext } from '../../constants.telemetry';
1616
import type { Container } from '../../container';
17+
import { AuthenticationError } from '../../errors';
1718
import type { Account } from '../../git/models/author';
1819
import type { IssueShape } from '../../git/models/issue';
1920
import type { PullRequest } from '../../git/models/pullRequest';
@@ -795,7 +796,7 @@ export class IntegrationService implements Disposable {
795796
const successfulResults = [
796797
...flatten(
797798
filterMap(results, r =>
798-
r.status === 'fulfilled' && r.value != null && r.value?.error == null ? r.value.value : undefined,
799+
r.status === 'fulfilled' && r.value?.value != null ? r.value.value : undefined,
799800
),
800801
),
801802
];
@@ -804,15 +805,13 @@ export class IntegrationService implements Disposable {
804805
r.status === 'fulfilled' && r.value?.error != null ? r.value.error : undefined,
805806
),
806807
];
807-
if (errors.length > 0 && successfulResults.length === 0) {
808-
return {
809-
error: errors.length === 1 ? errors[0] : new AggregateError(errors),
810-
duration: Date.now() - start,
811-
};
812-
}
808+
809+
const firstAuthError = errors.find(ex => ex instanceof AuthenticationError);
810+
const error = firstAuthError ?? errors[0];
813811

814812
return {
815813
value: successfulResults,
814+
error: error,
816815
duration: Date.now() - start,
817816
};
818817
}

src/plus/integrations/models/integration.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ export type IntegrationKey<T extends IntegrationIds = IntegrationIds> = T extend
4646
export type IntegrationConnectedKey<T extends IntegrationIds = IntegrationIds> = `connected:${IntegrationKey<T>}`;
4747

4848
export type IntegrationResult<T> =
49-
| { value: T; duration?: number; error?: never }
49+
| { value: T; duration?: number; error?: Error }
5050
| { error: Error; duration?: number; value?: never }
5151
| undefined;
5252

src/plus/launchpad/launchpad.ts

Lines changed: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -568,7 +568,7 @@ export class LaunchpadCommand extends QuickCommand<State> {
568568
function getItemsAndQuickpickProps(isFiltering?: boolean) {
569569
const result = context.inSearch ? context.searchResult : context.result;
570570

571-
if (result?.error != null) {
571+
if (result?.error != null && !result?.items?.length) {
572572
return {
573573
title: `${context.title} \u00a0\u2022\u00a0 Unable to Load Items`,
574574
placeholder: `Unable to load items (${
@@ -582,7 +582,7 @@ export class LaunchpadCommand extends QuickCommand<State> {
582582
};
583583
}
584584

585-
if (!result?.items.length) {
585+
if (!result?.items?.length) {
586586
if (context.inSearch === 'mode') {
587587
return {
588588
title: `Search For Pull Request \u00a0\u2022\u00a0 ${context.title}`,
@@ -616,6 +616,21 @@ export class LaunchpadCommand extends QuickCommand<State> {
616616
}
617617

618618
const items = getLaunchpadQuickPickItems(result.items, isFiltering);
619+
620+
// Add error information item if there's an error but items were still loaded
621+
const errorItem: DirectiveQuickPickItem | undefined =
622+
result?.error != null
623+
? createDirectiveQuickPickItem(Directive.Noop, false, {
624+
label: '$(warning) Unable to fully load items',
625+
detail:
626+
result.error.name === 'HttpError' &&
627+
'status' in result.error &&
628+
typeof result.error.status === 'number'
629+
? `${result.error.status}: ${String(result.error)}`
630+
: String(result.error),
631+
})
632+
: undefined;
633+
619634
const hasPicked = items.some(i => i.picked);
620635
if (context.inSearch === 'mode') {
621636
const offItem: ToggleSearchModeQuickPickItem = {
@@ -630,7 +645,9 @@ export class LaunchpadCommand extends QuickCommand<State> {
630645
return {
631646
title: `Search For Pull Request \u00a0\u2022\u00a0 ${context.title}`,
632647
placeholder: 'Enter a term to search for a pull request to act on',
633-
items: isFiltering ? [...items, offItem] : [offItem, ...items],
648+
items: isFiltering
649+
? [...(errorItem != null ? [errorItem] : []), ...items, offItem]
650+
: [offItem, ...(errorItem != null ? [errorItem] : []), ...items],
634651
};
635652
}
636653

@@ -646,8 +663,12 @@ export class LaunchpadCommand extends QuickCommand<State> {
646663
title: context.title,
647664
placeholder: 'Choose a pull request or paste a pull request URL to act on',
648665
items: isFiltering
649-
? [...items, onItem]
650-
: [onItem, ...getLaunchpadQuickPickItems(result.items, isFiltering)],
666+
? [...(errorItem != null ? [errorItem] : []), ...items, onItem]
667+
: [
668+
onItem,
669+
...(errorItem != null ? [errorItem] : []),
670+
...getLaunchpadQuickPickItems(result.items, isFiltering),
671+
],
651672
};
652673
}
653674

@@ -1657,10 +1678,10 @@ function updateTelemetryContext(context: Context) {
16571678
if (context.telemetryContext == null) return;
16581679

16591680
let updatedContext: NonNullable<(typeof context)['telemetryContext']>;
1660-
if (context.result.error != null) {
1681+
if (context.result.error != null || !context.result.items) {
16611682
updatedContext = {
16621683
...context.telemetryContext,
1663-
'items.error': String(context.result.error),
1684+
'items.error': String(context.result.error ?? 'items not loaded'),
16641685
};
16651686
} else {
16661687
const grouped = countLaunchpadItemGroups(context.result.items);

src/plus/launchpad/launchpadProvider.ts

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ export type LaunchpadCategorizedResult =
149149
| {
150150
items: LaunchpadItem[];
151151
timings?: LaunchpadCategorizedTimings;
152-
error?: never;
152+
error?: Error;
153153
}
154154
| {
155155
error: Error;
@@ -221,11 +221,6 @@ export class LaunchpadProvider implements Disposable {
221221
}
222222

223223
const prs = getSettledValue(prsResult)?.value;
224-
if (prs?.error != null) {
225-
Logger.error(prs.error, scope, 'Failed to get pull requests');
226-
throw prs.error;
227-
}
228-
229224
const subscription = getSettledValue(subscriptionResult);
230225

231226
let suggestionCounts;
@@ -252,7 +247,7 @@ export class LaunchpadProvider implements Disposable {
252247
search,
253248
connectedIntegrations,
254249
);
255-
const result: { readonly value: PullRequest[]; duration: number } = {
250+
const result: { readonly value: PullRequest[]; duration: number; error?: Error } = {
256251
value: [],
257252
duration: 0,
258253
};
@@ -690,7 +685,7 @@ export class LaunchpadProvider implements Disposable {
690685
isSearching
691686
? typeof options.search === 'string'
692687
? this.getSearchedPullRequests(options.search, cancellation)
693-
: { prs: { value: options.search, duration: 0 }, suggestionCounts: undefined }
688+
: { prs: { value: options.search, duration: 0, error: undefined }, suggestionCounts: undefined }
694689
: this.getPullRequestsWithSuggestionCounts({ force: options?.force, cancellation: cancellation }),
695690
]);
696691

@@ -719,6 +714,7 @@ export class LaunchpadProvider implements Disposable {
719714
codeSuggestionCounts: prsWithSuggestionCounts?.suggestionCounts?.duration,
720715
enrichedItems: enrichedItems?.duration,
721716
},
717+
error: prsWithSuggestionCounts?.prs?.error,
722718
};
723719
return result;
724720
}
@@ -848,6 +844,7 @@ export class LaunchpadProvider implements Disposable {
848844
codeSuggestionCounts: prsWithSuggestionCounts?.suggestionCounts?.duration,
849845
enrichedItems: enrichedItems?.duration,
850846
},
847+
error: prsWithSuggestionCounts?.prs?.error,
851848
};
852849
return result;
853850
} finally {

src/webviews/home/homeWebview.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1927,13 +1927,13 @@ async function getLaunchpadItemInfo(
19271927
): Promise<LaunchpadItemInfo> {
19281928
launchpadPromise ??= container.launchpad.getCategorizedItems();
19291929
let result = await launchpadPromise;
1930-
if (result.error != null) return undefined;
1930+
if (result.error != null || !result.items) return undefined;
19311931

19321932
let lpi = result.items.find(i => i.url === pr.url);
19331933
if (lpi == null) {
19341934
// result = await container.launchpad.getCategorizedItems({ search: pr.url });
19351935
result = await container.launchpad.getCategorizedItems({ search: [pr] });
1936-
if (result.error != null) return undefined;
1936+
if (result.error != null || !result.items) return undefined;
19371937

19381938
lpi = result.items.find(i => i.url === pr.url);
19391939
}

0 commit comments

Comments
 (0)