Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Show an error message when Launchpad fails to load data #45

Merged
merged 1 commit into from
Jun 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 48 additions & 18 deletions src/popup/components/FocusView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { storage } from 'webextension-polyfill';
import { getGitKrakenDeepLinkUrl } from '../../deepLink';
import { ProviderMeta } from '../../providers';
import { GKDotDevUrl } from '../../shared';
import type { FocusViewSupportedProvider } from '../../types';
import type { FocusViewDataError, FocusViewSupportedProvider } from '../../types';
import { useFocusViewConnectedProviders, useFocusViewDataQuery, usePullRequestDraftCountsQuery } from '../hooks';
import { ConnectAProvider } from './ConnectAProvider';
import { ExternalLink } from './ExternalLink';
Expand Down Expand Up @@ -189,6 +189,52 @@ export const FocusView = ({ userId }: { userId: string }) => {
return <ConnectAProvider />;
}

let content: JSX.Element | null = null;
if (focusViewDataQuery.isLoading) {
content = (
<div className="text-center">
<i className="fa-regular fa-spinner-third fa-spin" />
</div>
);
} else if (focusViewDataQuery.error) {
const error = focusViewDataQuery.error as FocusViewDataError;
content = (
<div className="focus-view-error text-secondary">
<div className="italic">
An unexpected error occurred trying to load Launchpad data.{' '}
{error.domain ? (
<>
Make sure the service at{' '}
<ExternalLink className="text-link" href={error.domain}>
{error.domain}
</ExternalLink>{' '}
is reachable. If it is, make sure your access token is still valid.
Comment on lines +207 to +211
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMO this message is a bit long. Normally I'd want to split it into two cases, one is the domain isn't reachable, and another is the access token is bad.

However I see that we can't distinguish that with the errors thrown by the provider-api package, so this is fine as-is.

</>
) : (
'Make sure your access token is still valid.'
)}
</div>
<ExternalLink className="text-link manage-integrations" href={`${GKDotDevUrl}/settings/integrations`}>
Manage Integration Settings
</ExternalLink>
</div>
);
} else {
content = (
<div className="pull-request-buckets">
{filteredBuckets?.map(bucket => (
<Bucket
key={bucket.id}
userId={userId}
bucket={bucket}
provider={selectedProvider}
prDraftCountsByEntityID={prDraftCountsQuery.data}
/>
))}
</div>
);
}

return (
<div className="focus-view">
{selectedProvider && (
Expand Down Expand Up @@ -224,23 +270,7 @@ export const FocusView = ({ userId }: { userId: string }) => {
</select>
</div>
)}
{focusViewDataQuery.isLoading ? (
<div className="text-center">
<i className="fa-regular fa-spinner-third fa-spin" />
</div>
) : (
<div className="pull-request-buckets">
{filteredBuckets?.map(bucket => (
<Bucket
key={bucket.id}
userId={userId}
bucket={bucket}
provider={selectedProvider}
prDraftCountsByEntityID={prDraftCountsQuery.data}
/>
))}
</div>
)}
{content}
</div>
);
};
37 changes: 22 additions & 15 deletions src/providers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -133,20 +133,27 @@ export const fetchFocusViewData = async (provider: FocusViewSupportedProvider):
return null;
}

switch (provider) {
case 'github':
case 'githubEnterprise':
return fetchGitHubFocusViewData(providerToken);
case 'gitlab':
case 'gitlabSelfHosted':
return fetchGitLabFocusViewData(providerToken);
case 'bitbucket':
return fetchBitbucketFocusViewData(providerToken);
case 'bitbucketServer':
return fetchBitbucketServerFocusViewData(providerToken);
case 'azure':
return fetchAzureFocusViewData(providerToken);
default:
throw new Error(`Attempted to fetch pull requests for unsupported provider: ${provider as Provider}`);
try {
switch (provider) {
case 'github':
case 'githubEnterprise':
return await fetchGitHubFocusViewData(providerToken);
case 'gitlab':
case 'gitlabSelfHosted':
return await fetchGitLabFocusViewData(providerToken);
case 'bitbucket':
return await fetchBitbucketFocusViewData(providerToken);
case 'bitbucketServer':
return await fetchBitbucketServerFocusViewData(providerToken);
case 'azure':
return await fetchAzureFocusViewData(providerToken);
default:
throw new Error(`Attempted to fetch pull requests for unsupported provider: ${provider as Provider}`);
}
} catch (e) {
if (e) {
Object.assign(e, { provider: provider, domain: providerToken.domain });
}
throw e;
}
};
5 changes: 5 additions & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,11 @@ export type FocusViewData = {
pullRequests: PullRequestWithUniqueID[];
};

export type FocusViewDataError = Error & {
provider?: Provider;
domain?: string;
};

export interface ProviderConnection {
provider: Provider;
type: string;
Expand Down
10 changes: 10 additions & 0 deletions static/popup.css
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,16 @@ html {
margin-right: 4px;
}

/* Focus View - Error */
.focus-view .focus-view-error {
display: flex;
flex-direction: column;
}
.focus-view .focus-view-error .manage-integrations {
text-align: center;
margin-top: 8px;
}

/* Generic components */
button.icon-btn {
background: none;
Expand Down
Loading