mirror of
https://github.com/gitbutlerapp/gitbutler.git
synced 2024-09-19 16:17:37 +03:00
Show most errors using toast
- does not automatically dismiss - shows the error to the user
This commit is contained in:
parent
4bb52ac831
commit
150acb0abf
@ -1,4 +1,5 @@
|
||||
import { invoke } from '$lib/backend/ipc';
|
||||
import { showError } from '$lib/notifications/toasts';
|
||||
import { persisted } from '$lib/persisted/persisted';
|
||||
import { observableToStore } from '$lib/rxjs/store';
|
||||
import * as toasts from '$lib/utils/toasts';
|
||||
@ -115,7 +116,7 @@ export class ProjectService {
|
||||
// linkProjectModal?.show(project.id);
|
||||
goto(`/${project.id}/board`);
|
||||
})
|
||||
.catch((e: any) => toasts.error(e.message));
|
||||
.catch((e: any) => showError('There was a problem', e.message));
|
||||
}
|
||||
|
||||
getLastOpenedProject() {
|
||||
|
@ -21,12 +21,12 @@
|
||||
DraggableRemoteCommit
|
||||
} from '$lib/dragging/draggables';
|
||||
import { dropzone } from '$lib/dragging/dropzone';
|
||||
import { showError } from '$lib/notifications/toasts';
|
||||
import { persisted } from '$lib/persisted/persisted';
|
||||
import { SETTINGS, type Settings } from '$lib/settings/userSettings';
|
||||
import { User } from '$lib/stores/user';
|
||||
import { getContext, getContextStore, getContextStoreBySymbol } from '$lib/utils/context';
|
||||
import { computeAddedRemovedByFiles } from '$lib/utils/metrics';
|
||||
import * as toasts from '$lib/utils/toasts';
|
||||
import { BranchController } from '$lib/vbranches/branchController';
|
||||
import { FileIdSelection } from '$lib/vbranches/fileIdSelection';
|
||||
import { filesToOwnership } from '$lib/vbranches/ownership';
|
||||
@ -84,7 +84,7 @@
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
toasts.error('Failed to generate branch name');
|
||||
showError('Failed to generate branch name', e);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -7,11 +7,10 @@
|
||||
import { clickOutside } from '$lib/clickOutside';
|
||||
import Button from '$lib/components/Button.svelte';
|
||||
import Icon from '$lib/components/Icon.svelte';
|
||||
import { showError } from '$lib/notifications/toasts';
|
||||
import { getContext, getContextStore } from '$lib/utils/context';
|
||||
import * as toasts from '$lib/utils/toasts';
|
||||
import { BranchController } from '$lib/vbranches/branchController';
|
||||
import { Branch } from '$lib/vbranches/types';
|
||||
import toast from 'svelte-french-toast';
|
||||
import type { Persisted } from '$lib/persisted/persisted';
|
||||
import { goto } from '$app/navigation';
|
||||
|
||||
@ -157,10 +156,9 @@
|
||||
try {
|
||||
await branchController.deleteBranch(branch.id);
|
||||
goto(`/${project.id}/board`);
|
||||
} catch (e) {
|
||||
const err = 'Failed to delete branch';
|
||||
toasts.error(err);
|
||||
console.error(err, e);
|
||||
} catch (err) {
|
||||
showError('Failed to delete branch', err);
|
||||
console.error(err);
|
||||
} finally {
|
||||
isDeleting = false;
|
||||
}
|
||||
@ -179,10 +177,9 @@
|
||||
try {
|
||||
await branchController.applyBranch(branch.id);
|
||||
goto(`/${project.id}/board`);
|
||||
} catch (e) {
|
||||
const err = 'Failed to apply branch';
|
||||
toast.error(err);
|
||||
console.error(err, e);
|
||||
} catch (err) {
|
||||
showError('Failed to apply branch', err);
|
||||
console.error(err);
|
||||
} finally {
|
||||
isApplying = false;
|
||||
}
|
||||
|
@ -14,10 +14,10 @@
|
||||
projectRunCommitHooks,
|
||||
persistedCommitMessage
|
||||
} from '$lib/config/config';
|
||||
import { showError } from '$lib/notifications/toasts';
|
||||
import { User } from '$lib/stores/user';
|
||||
import { splitMessage } from '$lib/utils/commitMessage';
|
||||
import { getContext, getContextStore } from '$lib/utils/context';
|
||||
import * as toasts from '$lib/utils/toasts';
|
||||
import { tooltip } from '$lib/utils/tooltip';
|
||||
import { setAutoHeight } from '$lib/utils/useAutoHeight';
|
||||
import { useResize } from '$lib/utils/useResize';
|
||||
@ -113,10 +113,10 @@
|
||||
if (generatedMessage) {
|
||||
$commitMessage = generatedMessage;
|
||||
} else {
|
||||
toasts.error('Failed to generate commit message');
|
||||
throw new Error('Prompt generated no response');
|
||||
}
|
||||
} catch {
|
||||
toasts.error('Failed to generate commit message');
|
||||
} catch (e: any) {
|
||||
showError('Failed to generate commit message', e);
|
||||
} finally {
|
||||
aiLoading = false;
|
||||
}
|
||||
|
@ -9,9 +9,9 @@
|
||||
import Button from '$lib/components/Button.svelte';
|
||||
import Link from '$lib/components/Link.svelte';
|
||||
import Section from '$lib/components/settings/Section.svelte';
|
||||
import { showError } from '$lib/notifications/toasts';
|
||||
import { copyToClipboard } from '$lib/utils/clipboard';
|
||||
import { getContext, getContextStore } from '$lib/utils/context';
|
||||
import * as toasts from '$lib/utils/toasts';
|
||||
import { openExternalUrl } from '$lib/utils/url';
|
||||
import { BaseBranch } from '$lib/vbranches/types';
|
||||
import { onMount } from 'svelte';
|
||||
@ -51,7 +51,7 @@
|
||||
try {
|
||||
projectService.updateProject({ ...project, ...detail });
|
||||
} catch (err: any) {
|
||||
toasts.error(err.message);
|
||||
showError('Failed to update key', err);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,8 +1,8 @@
|
||||
<script lang="ts">
|
||||
import Button from './Button.svelte';
|
||||
import { showError } from '$lib/notifications/toasts';
|
||||
import { UserService, type LoginToken } from '$lib/stores/user';
|
||||
import { getContext } from '$lib/utils/context';
|
||||
import * as toasts from '$lib/utils/toasts';
|
||||
import { openExternalUrl } from '$lib/utils/url';
|
||||
|
||||
const userService = getContext(UserService);
|
||||
@ -54,7 +54,7 @@
|
||||
await userService.login(token);
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
toasts.error('Could not create login token');
|
||||
showError('Could not create login token', err);
|
||||
} finally {
|
||||
signUpOrLoginLoading = false;
|
||||
}
|
||||
|
@ -7,6 +7,7 @@
|
||||
import RemoveProjectButton from './RemoveProjectButton.svelte';
|
||||
import derectionDoubtSvg from '$lib/assets/illustrations/direction-doubt.svg?raw';
|
||||
import { ProjectService, Project } from '$lib/backend/projects';
|
||||
import { showError } from '$lib/notifications/toasts';
|
||||
import { getContext } from '$lib/utils/context';
|
||||
import * as toasts from '$lib/utils/toasts';
|
||||
import { BranchController } from '$lib/vbranches/branchController';
|
||||
@ -30,9 +31,9 @@
|
||||
await projectService.deleteProject(project.id);
|
||||
toasts.success('Project deleted');
|
||||
goto('/', { invalidateAll: true });
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
toasts.error('Failed to delete project');
|
||||
} catch (err: any) {
|
||||
console.error(err);
|
||||
showError('Failed to delete project', err);
|
||||
} finally {
|
||||
isDeleting = false;
|
||||
projectService.reload();
|
||||
|
@ -2,8 +2,8 @@
|
||||
import Button from './Button.svelte';
|
||||
import TextBox from './TextBox.svelte';
|
||||
import { PromptService, type SystemPrompt } from '$lib/backend/prompt';
|
||||
import { showError } from '$lib/notifications/toasts';
|
||||
import { getContext } from '$lib/utils/context';
|
||||
import * as toasts from '$lib/utils/toasts';
|
||||
|
||||
export let prompt: SystemPrompt | undefined;
|
||||
export let error: any;
|
||||
@ -21,7 +21,7 @@
|
||||
isSubmitting = false;
|
||||
}
|
||||
|
||||
if (error) toasts.error(error);
|
||||
if (error) showError('Something went wrong', error);
|
||||
</script>
|
||||
|
||||
{#if prompt}
|
||||
|
@ -5,6 +5,7 @@
|
||||
import loadErrorSvg from '$lib/assets/illustrations/load-error.svg?raw';
|
||||
import { ProjectService, Project } from '$lib/backend/projects';
|
||||
import Icon from '$lib/components/Icon.svelte';
|
||||
import { showError } from '$lib/notifications/toasts';
|
||||
import { getContext } from '$lib/utils/context';
|
||||
import * as toasts from '$lib/utils/toasts';
|
||||
import { goto } from '$app/navigation';
|
||||
@ -24,9 +25,9 @@
|
||||
await projectService.deleteProject(project.id);
|
||||
toasts.success('Project deleted');
|
||||
goto('/');
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
toasts.error('Failed to delete project');
|
||||
} catch (err: any) {
|
||||
console.error(err);
|
||||
showError('Failed to delete project', err);
|
||||
} finally {
|
||||
loading = false;
|
||||
projectService.reload();
|
||||
|
@ -1,7 +1,7 @@
|
||||
<script lang="ts">
|
||||
import Tag from './Tag.svelte';
|
||||
import { showError } from '$lib/notifications/toasts';
|
||||
import { getContext } from '$lib/utils/context';
|
||||
import * as toasts from '$lib/utils/toasts';
|
||||
import { BranchController } from '$lib/vbranches/branchController';
|
||||
|
||||
const branchController = getContext(BranchController);
|
||||
@ -18,8 +18,8 @@
|
||||
loading = true;
|
||||
try {
|
||||
await branchController.updateBaseBranch();
|
||||
} catch {
|
||||
toasts.error('Failed update workspace');
|
||||
} catch (err) {
|
||||
showError('Failed update workspace', err);
|
||||
} finally {
|
||||
loading = false;
|
||||
}
|
||||
|
@ -8,7 +8,7 @@ import {
|
||||
parseGitHubCheckSuites,
|
||||
type CheckSuites
|
||||
} from '$lib/github/types';
|
||||
import { showToast, type Toast } from '$lib/notifications/toasts';
|
||||
import { showError, showToast, type Toast } from '$lib/notifications/toasts';
|
||||
import { sleep } from '$lib/utils/sleep';
|
||||
import * as toasts from '$lib/utils/toasts';
|
||||
import { Octokit } from '@octokit/rest';
|
||||
@ -97,7 +97,7 @@ export class GitHubService {
|
||||
shareReplay(1),
|
||||
catchError((err) => {
|
||||
console.error(err);
|
||||
toasts.error('Failed to load pull requests');
|
||||
showError('Failed to load pull requests', err);
|
||||
this.error$.next(err);
|
||||
return of([]);
|
||||
}),
|
||||
|
@ -21,6 +21,13 @@ export function showToast(toast: Toast) {
|
||||
]);
|
||||
}
|
||||
|
||||
export function showError(title: string, err: any) {
|
||||
let message: string;
|
||||
if (err.message) message = err.message;
|
||||
message = `\`\`\`${err}\`\`\``; // markdown code block
|
||||
showToast({ title, message, style: 'error' });
|
||||
}
|
||||
|
||||
export function dismissToast(messageId: string | undefined) {
|
||||
if (!messageId) return;
|
||||
toastStore.update((items) => items.filter((m) => m.id != messageId));
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { invoke } from '$lib/backend/ipc';
|
||||
import { showError } from '$lib/notifications/toasts';
|
||||
import { observableToStore } from '$lib/rxjs/store';
|
||||
import * as toasts from '$lib/utils/toasts';
|
||||
import { RemoteBranch, RemoteBranchData } from '$lib/vbranches/types';
|
||||
import { plainToInstance } from 'class-transformer';
|
||||
import {
|
||||
@ -32,7 +32,7 @@ export class RemoteBranchService {
|
||||
shareReplay(1),
|
||||
catchError((e) => {
|
||||
console.error(e);
|
||||
toasts.error(`Failed load remote branches`);
|
||||
showError('Failed load remote branches', e);
|
||||
throw e;
|
||||
})
|
||||
);
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { BaseBranch } from './types';
|
||||
import { Code, invoke } from '$lib/backend/ipc';
|
||||
import { showError } from '$lib/notifications/toasts';
|
||||
import { observableToStore } from '$lib/rxjs/store';
|
||||
import * as toasts from '$lib/utils/toasts';
|
||||
import { plainToInstance } from 'class-transformer';
|
||||
import {
|
||||
switchMap,
|
||||
@ -77,9 +77,9 @@ export class BaseBranchService {
|
||||
// Swallow this error since user should be taken to project setup page
|
||||
return;
|
||||
} else if (err.code === Code.ProjectsGitAuth) {
|
||||
toasts.error('Failed to authenticate. Did you setup GitButler ssh keys?');
|
||||
showError('Failed to authenticate', err);
|
||||
} else {
|
||||
toasts.error(`${err.message}`);
|
||||
showError('Failed to fetch', err);
|
||||
}
|
||||
console.error(err);
|
||||
} finally {
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { invoke } from '$lib/backend/ipc';
|
||||
import { showToast } from '$lib/notifications/toasts';
|
||||
import { showError, showToast } from '$lib/notifications/toasts';
|
||||
import * as toasts from '$lib/utils/toasts';
|
||||
import posthog from 'posthog-js';
|
||||
import type { RemoteBranchService } from '$lib/stores/remoteBranches';
|
||||
@ -19,8 +19,8 @@ export class BranchController {
|
||||
try {
|
||||
await this.targetBranchService.setTarget(branch);
|
||||
// TODO: Reloading seems to trigger 4 invocations of `list_virtual_branches`
|
||||
} catch (err) {
|
||||
toasts.error('Failed to set base branch');
|
||||
} catch (err: any) {
|
||||
showError('Failed to set base branch', err);
|
||||
} finally {
|
||||
this.targetBranchService.reload();
|
||||
this.vbranchService.reload();
|
||||
@ -35,7 +35,7 @@ export class BranchController {
|
||||
targetCommitOid
|
||||
});
|
||||
} catch (err) {
|
||||
toasts.error('Failed to reset branch');
|
||||
showError('Failed to reset branch', err);
|
||||
}
|
||||
}
|
||||
|
||||
@ -43,7 +43,7 @@ export class BranchController {
|
||||
try {
|
||||
await invoke<void>('create_virtual_branch', { projectId: this.projectId, branch });
|
||||
} catch (err) {
|
||||
toasts.error('Failed to create branch');
|
||||
showError('Failed to create branch', err);
|
||||
}
|
||||
}
|
||||
|
||||
@ -63,7 +63,7 @@ export class BranchController {
|
||||
});
|
||||
posthog.capture('Commit Successful');
|
||||
} catch (err: any) {
|
||||
toasts.error('Failed to commit changes');
|
||||
showError('Failed to commit changes', err);
|
||||
posthog.capture('Commit Failed', err);
|
||||
throw err;
|
||||
}
|
||||
@ -76,7 +76,7 @@ export class BranchController {
|
||||
branch
|
||||
});
|
||||
} catch (err) {
|
||||
toasts.error('Failed to merge upstream branch');
|
||||
showError('Failed to merge upstream branch', err);
|
||||
}
|
||||
}
|
||||
|
||||
@ -87,7 +87,7 @@ export class BranchController {
|
||||
branch: { id: branchId, name }
|
||||
});
|
||||
} catch (err) {
|
||||
toasts.error('Failed to update branch name');
|
||||
showError('Failed to update branch name', err);
|
||||
}
|
||||
}
|
||||
|
||||
@ -98,7 +98,7 @@ export class BranchController {
|
||||
branch: { id: branchId, upstream }
|
||||
});
|
||||
} catch (err) {
|
||||
toasts.error('Failed to update branch remote name');
|
||||
showError('Failed to update remote name', err);
|
||||
}
|
||||
}
|
||||
|
||||
@ -109,7 +109,7 @@ export class BranchController {
|
||||
branch: { id: branchId, notes }
|
||||
});
|
||||
} catch (err) {
|
||||
toasts.error('Failed to update branch notes');
|
||||
showError('Failed to update branch notes', err);
|
||||
}
|
||||
}
|
||||
|
||||
@ -120,7 +120,7 @@ export class BranchController {
|
||||
branch: { id: branchId, selected_for_changes: true }
|
||||
});
|
||||
} catch (err) {
|
||||
toasts.error('Failed to set as target');
|
||||
showError('Failed make default target', err);
|
||||
}
|
||||
}
|
||||
|
||||
@ -131,7 +131,7 @@ export class BranchController {
|
||||
branch: { id: branchId, order }
|
||||
});
|
||||
} catch (err) {
|
||||
toasts.error('Failed to update branch order');
|
||||
showError('Failed to update branch order', err);
|
||||
}
|
||||
}
|
||||
|
||||
@ -140,7 +140,7 @@ export class BranchController {
|
||||
// TODO: make this optimistic again.
|
||||
await invoke<void>('apply_branch', { projectId: this.projectId, branch: branchId });
|
||||
} catch (err) {
|
||||
toasts.error('Failed to apply branch');
|
||||
showError('Failed to apply branch', err);
|
||||
}
|
||||
}
|
||||
|
||||
@ -149,7 +149,7 @@ export class BranchController {
|
||||
try {
|
||||
await invoke<void>('unapply_ownership', { projectId: this.projectId, ownership });
|
||||
} catch (err) {
|
||||
toasts.error('Failed to unapply hunk');
|
||||
showError('Failed to unapply hunk', err);
|
||||
}
|
||||
}
|
||||
|
||||
@ -160,7 +160,7 @@ export class BranchController {
|
||||
files: files.flatMap((f) => f.path).join('\n')
|
||||
});
|
||||
} catch (err) {
|
||||
toasts.error('Failed to unapply file changes');
|
||||
showError('Failed to unapply file changes', err);
|
||||
}
|
||||
}
|
||||
|
||||
@ -169,7 +169,7 @@ export class BranchController {
|
||||
// TODO: make this optimistic again.
|
||||
await invoke<void>('unapply_branch', { projectId: this.projectId, branch: branchId });
|
||||
} catch (err) {
|
||||
toasts.error('Failed to unapply branch');
|
||||
showError('Failed to unapply branch', err);
|
||||
}
|
||||
}
|
||||
|
||||
@ -180,7 +180,7 @@ export class BranchController {
|
||||
branch: { id: branchId, ownership }
|
||||
});
|
||||
} catch (err) {
|
||||
toasts.error('Failed to update branch ownership');
|
||||
showError('Failed to update hunk ownership', err);
|
||||
}
|
||||
}
|
||||
|
||||
@ -233,7 +233,7 @@ export class BranchController {
|
||||
await invoke<void>('delete_virtual_branch', { projectId: this.projectId, branchId });
|
||||
toasts.success('Branch deleted successfully');
|
||||
} catch (err) {
|
||||
toasts.error('Failed to delete branch');
|
||||
showError('Failed to delete branch', err);
|
||||
} finally {
|
||||
this.remoteBranchService.reload();
|
||||
}
|
||||
@ -254,7 +254,7 @@ export class BranchController {
|
||||
branch
|
||||
});
|
||||
} catch (err) {
|
||||
toasts.error('Failed to create virtual branch from branch');
|
||||
showError('Failed to create virtual branch', err);
|
||||
} finally {
|
||||
this.remoteBranchService.reload();
|
||||
this.targetBranchService.reload();
|
||||
@ -269,7 +269,7 @@ export class BranchController {
|
||||
targetCommitOid
|
||||
});
|
||||
} catch (err: any) {
|
||||
toasts.error(`Failed to cherry-pick commit: ${err.message}`);
|
||||
showError('Failed to cherry-pick commit', err);
|
||||
} finally {
|
||||
this.targetBranchService.reload();
|
||||
}
|
||||
@ -279,7 +279,7 @@ export class BranchController {
|
||||
try {
|
||||
await invoke<void>('mark_resolved', { projectId: this.projectId, path });
|
||||
} catch (err) {
|
||||
toasts.error(`Failed to mark file resolved`);
|
||||
showError('Failed to mark file resolved', err);
|
||||
}
|
||||
}
|
||||
|
||||
@ -291,7 +291,7 @@ export class BranchController {
|
||||
targetCommitOid
|
||||
});
|
||||
} catch (err: any) {
|
||||
toasts.error(`Failed to squash commit: ${err.message}`);
|
||||
showError('Failed to squash commit', err);
|
||||
}
|
||||
}
|
||||
|
||||
@ -303,7 +303,7 @@ export class BranchController {
|
||||
ownership
|
||||
});
|
||||
} catch (err: any) {
|
||||
toasts.error(`Failed to amend commit: ${err.message}`);
|
||||
showError('Failed to amend commit', err);
|
||||
}
|
||||
}
|
||||
|
||||
@ -315,7 +315,7 @@ export class BranchController {
|
||||
commitOid
|
||||
});
|
||||
} catch (err: any) {
|
||||
toasts.error(`Failed to move commit: ${err.message}`);
|
||||
showError('Failed to move commit', err);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -8,6 +8,7 @@
|
||||
import SectionCard from '$lib/components/SectionCard.svelte';
|
||||
import Spacer from '$lib/components/Spacer.svelte';
|
||||
import ContentWrapper from '$lib/components/settings/ContentWrapper.svelte';
|
||||
import { showError } from '$lib/notifications/toasts';
|
||||
import { UserService } from '$lib/stores/user';
|
||||
import { getContext } from '$lib/utils/context';
|
||||
import * as toasts from '$lib/utils/toasts';
|
||||
@ -39,7 +40,7 @@
|
||||
toasts.success('Project deleted');
|
||||
} catch (err: any) {
|
||||
console.error(err);
|
||||
toasts.error('Failed to delete project');
|
||||
showError('Failed to delete project', err);
|
||||
} finally {
|
||||
isDeleting = false;
|
||||
}
|
||||
|
@ -10,6 +10,7 @@
|
||||
import Toggle from '$lib/components/Toggle.svelte';
|
||||
import WelcomeSigninAction from '$lib/components/WelcomeSigninAction.svelte';
|
||||
import ContentWrapper from '$lib/components/settings/ContentWrapper.svelte';
|
||||
import { showError } from '$lib/notifications/toasts';
|
||||
import { SETTINGS, type Settings } from '$lib/settings/userSettings';
|
||||
import { UserService } from '$lib/stores/user';
|
||||
import { getContext, getContextStoreBySymbol } from '$lib/utils/context';
|
||||
@ -58,9 +59,9 @@
|
||||
updatedUser.github_access_token = $user?.github_access_token; // prevent overwriting with null
|
||||
userService.setUser(updatedUser);
|
||||
toasts.success('Profile updated');
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
toasts.error('Failed to update user');
|
||||
} catch (err: any) {
|
||||
console.error(err);
|
||||
showError('Failed to update user', err);
|
||||
}
|
||||
saving = false;
|
||||
}
|
||||
@ -87,7 +88,7 @@
|
||||
goto('/', { replaceState: true, invalidateAll: true });
|
||||
} catch (err: any) {
|
||||
console.error(err);
|
||||
toasts.error('Failed to delete project');
|
||||
showError('Failed to delete project', err);
|
||||
} finally {
|
||||
deleteConfirmationModal.close();
|
||||
isDeleting = false;
|
||||
|
Loading…
Reference in New Issue
Block a user