diff --git a/apps/electron/layers/main/src/application-menu/create.ts b/apps/electron/layers/main/src/application-menu/create.ts index a3e096a623..930a11cfff 100644 --- a/apps/electron/layers/main/src/application-menu/create.ts +++ b/apps/electron/layers/main/src/application-menu/create.ts @@ -119,7 +119,7 @@ export function createApplicationMenu() { { label: 'Open log file', click: async () => { - revealLogFile(); + await revealLogFile(); }, }, { diff --git a/apps/electron/layers/main/src/db/__tests__/workspace-db-adapter.spec.ts b/apps/electron/layers/main/src/db/__tests__/workspace-db-adapter.spec.ts index 86b0a49a04..10dd8fa8a9 100644 --- a/apps/electron/layers/main/src/db/__tests__/workspace-db-adapter.spec.ts +++ b/apps/electron/layers/main/src/db/__tests__/workspace-db-adapter.spec.ts @@ -62,7 +62,7 @@ test('on applyUpdate (from renderer), will trigger update', async () => { db.update$.subscribe(onUpdate); const sub = dbSubjects.externalUpdate.subscribe(onExternalUpdate); db.applyUpdate(getTestUpdates(), 'renderer'); - expect(onUpdate).toHaveBeenCalled(); // not yet updated + expect(onUpdate).toHaveBeenCalled(); sub.unsubscribe(); await db.destroy(); }); diff --git a/apps/electron/layers/main/src/db/ensure-db.ts b/apps/electron/layers/main/src/db/ensure-db.ts index 36a9e2851a..96992b418c 100644 --- a/apps/electron/layers/main/src/db/ensure-db.ts +++ b/apps/electron/layers/main/src/db/ensure-db.ts @@ -11,6 +11,7 @@ import { merge, } from 'rxjs'; import { + concatMap, distinctUntilChanged, filter, ignoreElements, @@ -126,10 +127,8 @@ function startPollingSecondaryDB(db: WorkspaceSQLiteDB) { switchMap(secondaryDB => { return interval(300000).pipe( startWith(0), + concatMap(() => secondaryDB.pull()), tap({ - next: () => { - secondaryDB.pull(); - }, error: err => { logger.error(`[ensureSQLiteDB] polling secondary db error`, err); }, diff --git a/apps/electron/layers/main/src/db/secondary-db.ts b/apps/electron/layers/main/src/db/secondary-db.ts index 66a0ee746d..5dc1c39633 100644 --- a/apps/electron/layers/main/src/db/secondary-db.ts +++ b/apps/electron/layers/main/src/db/secondary-db.ts @@ -93,6 +93,7 @@ export class SecondaryWorkspaceSQLiteDB extends BaseSQLiteAdapter { return await fn(); } catch (err) { logger.error(err); + throw err; } finally { this.runCounter--; if (this.runCounter === 0) { @@ -115,10 +116,10 @@ export class SecondaryWorkspaceSQLiteDB extends BaseSQLiteAdapter { } }; - const onSelfUpdate = (update: Uint8Array, origin: YOrigin) => { + const onSelfUpdate = async (update: Uint8Array, origin: YOrigin) => { // for self update from upstream, we need to push it to external DB if (origin === 'upstream' && this.db) { - this.addUpdateToUpdateQueue(this.db, update); + await this.addUpdateToUpdateQueue(this.db, update); } if (origin === 'self') { @@ -135,12 +136,18 @@ export class SecondaryWorkspaceSQLiteDB extends BaseSQLiteAdapter { this.yDoc.off('update', onSelfUpdate); }); - this.run(async () => { + this.run(() => { // apply all updates from upstream const upstreamUpdate = this.upstream.getDocAsUpdates(); // to initialize the yDoc, we need to apply all updates from the db this.applyUpdate(upstreamUpdate, 'upstream'); - }); + }) + .then(() => { + logger.debug('run success'); + }) + .catch(err => { + logger.error('run error', err); + }); } applyUpdate = (data: Uint8Array, origin: YOrigin = 'upstream') => { diff --git a/apps/electron/layers/main/src/db/workspace-db-adapter.ts b/apps/electron/layers/main/src/db/workspace-db-adapter.ts index f343f19c6a..181e986687 100644 --- a/apps/electron/layers/main/src/db/workspace-db-adapter.ts +++ b/apps/electron/layers/main/src/db/workspace-db-adapter.ts @@ -79,19 +79,19 @@ export class WorkspaceSQLiteDB extends BaseSQLiteAdapter { }; override async addBlob(key: string, value: Uint8Array) { - const res = await super.addBlob(key, value); this.update$.next(); + const res = await super.addBlob(key, value); return res; } override async deleteBlob(key: string) { - super.deleteBlob(key); this.update$.next(); + await super.deleteBlob(key); } override async addUpdateToSQLite(db: SqliteConnection, data: Uint8Array[]) { - super.addUpdateToSQLite(db, data); this.update$.next(); + await super.addUpdateToSQLite(db, data); } } diff --git a/apps/electron/layers/main/src/dialog/dialog.ts b/apps/electron/layers/main/src/dialog/dialog.ts index fc83183ba9..372b73e3ce 100644 --- a/apps/electron/layers/main/src/dialog/dialog.ts +++ b/apps/electron/layers/main/src/dialog/dialog.ts @@ -320,7 +320,7 @@ export async function moveDBFile( filePath: newFilePath, }; } catch (err) { - db?.destroy(); + await db?.destroy(); logger.error('[moveDBFile]', err); return { error: 'UNKNOWN_ERROR', diff --git a/apps/electron/layers/main/src/export/pdf.ts b/apps/electron/layers/main/src/export/pdf.ts index 40a06aa11f..b54d4ea4bf 100644 --- a/apps/electron/layers/main/src/export/pdf.ts +++ b/apps/electron/layers/main/src/export/pdf.ts @@ -50,7 +50,7 @@ export async function savePDFFileAs( }); }); - shell.openPath(filePath); + await shell.openPath(filePath); return { filePath }; } catch (err) { logger.error('savePDFFileAs', err); diff --git a/apps/electron/layers/main/src/index.ts b/apps/electron/layers/main/src/index.ts index 9c4bee2da2..e603c73d5c 100644 --- a/apps/electron/layers/main/src/index.ts +++ b/apps/electron/layers/main/src/index.ts @@ -29,7 +29,9 @@ if (!isSingleInstance) { } app.on('second-instance', () => { - restoreOrCreateWindow(); + restoreOrCreateWindow().catch(e => + console.error('Failed to restore or create window:', e) + ); }); app.on('open-url', async (_, _url) => { diff --git a/apps/electron/layers/main/src/ui/google-auth.ts b/apps/electron/layers/main/src/ui/google-auth.ts index 2a41a75b23..be929f40fd 100644 --- a/apps/electron/layers/main/src/ui/google-auth.ts +++ b/apps/electron/layers/main/src/ui/google-auth.ts @@ -28,10 +28,12 @@ export const getExchangeTokenParams = (code: string) => { }; export function getGoogleOauthCode() { - shell.openExternal(oauthEndpoint); - return new Promise>( (resolve, reject) => { + shell.openExternal(oauthEndpoint).catch(e => { + logger.error('Failed to open external url', e); + reject(e); + }); const handleOpenUrl = async (_: any, url: string) => { const mainWindow = BrowserWindow.getAllWindows().find( w => !w.isDestroyed() diff --git a/apps/electron/layers/main/src/updater/electron-updater.ts b/apps/electron/layers/main/src/updater/electron-updater.ts index 8f0e864621..3b3f2f8c8a 100644 --- a/apps/electron/layers/main/src/updater/electron-updater.ts +++ b/apps/electron/layers/main/src/updater/electron-updater.ts @@ -67,7 +67,9 @@ export const registerUpdater = async () => { // register events for checkForUpdatesAndNotify _autoUpdater.on('update-available', info => { if (allowAutoUpdate) { - _autoUpdater?.downloadUpdate(); + _autoUpdater?.downloadUpdate().catch(e => { + logger.error('Failed to download update', e); + }); logger.info('Update available, downloading...', info); } updaterSubjects.updateAvailable.next({ diff --git a/apps/web/src/adapters/local/index.tsx b/apps/web/src/adapters/local/index.tsx index 04620ae61e..158734a8a8 100644 --- a/apps/web/src/adapters/local/index.tsx +++ b/apps/web/src/adapters/local/index.tsx @@ -46,7 +46,9 @@ export const LocalAdapter: WorkspaceAdapter = { }); setEditorFlags(blockSuiteWorkspace); if (config.enablePreloading) { - initPageWithPreloading(page); + initPageWithPreloading(page).catch(err => { + logger.error('init page with preloading failed', err); + }); } else { initEmptyPage(page); } diff --git a/apps/web/src/components/affine/affine-error-eoundary.tsx b/apps/web/src/components/affine/affine-error-eoundary.tsx index 5003c90cf8..2cd79fe52b 100644 --- a/apps/web/src/components/affine/affine-error-eoundary.tsx +++ b/apps/web/src/components/affine/affine-error-eoundary.tsx @@ -67,7 +67,7 @@ export class AffineErrorBoundary extends Component< pageId: error.workspace.meta.pageMetas[0].id, }, }) - .then(() => { + .finally(() => { this.setState({ error: null }); }); }} diff --git a/apps/web/src/components/affine/workspace-setting-detail/index.tsx b/apps/web/src/components/affine/workspace-setting-detail/index.tsx index 26f535f913..089ec8d3de 100644 --- a/apps/web/src/components/affine/workspace-setting-detail/index.tsx +++ b/apps/web/src/components/affine/workspace-setting-detail/index.tsx @@ -95,7 +95,7 @@ export const WorkspaceSettingDetail: React.FC< const workspaceId = workspace.id; useEffect(() => { if (isAffine && isOwner) { - preload([QueryKey.getMembers, workspaceId], fetcher); + preload([QueryKey.getMembers, workspaceId], fetcher).catch(console.error); } }, [isAffine, isOwner, workspaceId]); const containerRef = useRef(null); diff --git a/apps/web/src/components/affine/workspace-setting-detail/panel/publish/index.tsx b/apps/web/src/components/affine/workspace-setting-detail/panel/publish/index.tsx index 9eaac4eba2..f96ae5a50e 100644 --- a/apps/web/src/components/affine/workspace-setting-detail/panel/publish/index.tsx +++ b/apps/web/src/components/affine/workspace-setting-detail/panel/publish/index.tsx @@ -46,8 +46,8 @@ const PublishPanelAffine: React.FC = ({ const shareUrl = origin + '/public-workspace/' + workspace.id; const t = useAFFiNEI18N(); const publishWorkspace = useToggleWorkspacePublish(workspace); - const copyUrl = useCallback(() => { - navigator.clipboard.writeText(shareUrl); + const copyUrl = useCallback(async () => { + await navigator.clipboard.writeText(shareUrl); toast(t['Copied link to clipboard']()); }, [shareUrl, t]); diff --git a/apps/web/src/components/blocksuite/block-suite-page-list/utils.tsx b/apps/web/src/components/blocksuite/block-suite-page-list/utils.tsx index 03d0a17414..99103789ad 100644 --- a/apps/web/src/components/blocksuite/block-suite-page-list/utils.tsx +++ b/apps/web/src/components/blocksuite/block-suite-page-list/utils.tsx @@ -16,12 +16,12 @@ export const usePageHelper = (blockSuiteWorkspace: BlockSuiteWorkspace) => { const createPageAndOpen = () => { const page = createPage(); - openPage(blockSuiteWorkspace.id, page.id); + return openPage(blockSuiteWorkspace.id, page.id); }; const createEdgelessAndOpen = () => { const page = createPage(); setPreferredMode(page.id, 'edgeless'); - openPage(blockSuiteWorkspace.id, page.id); + return openPage(blockSuiteWorkspace.id, page.id); }; const importFileAndOpen = async () => { const { showImportModal } = await import('@blocksuite/blocks'); diff --git a/apps/web/src/components/blocksuite/workspace-header/header-right-items/edit-page.tsx b/apps/web/src/components/blocksuite/workspace-header/header-right-items/edit-page.tsx index e53f1a3236..388bef8e52 100644 --- a/apps/web/src/components/blocksuite/workspace-header/header-right-items/edit-page.tsx +++ b/apps/web/src/components/blocksuite/workspace-header/header-right-items/edit-page.tsx @@ -10,7 +10,9 @@ export const EditPage = () => { const { jumpToPage } = useRouterHelper(router); const onClickPage = useCallback(() => { if (workspaceId && pageId) { - jumpToPage(workspaceId, pageId); + jumpToPage(workspaceId, pageId).catch(error => { + console.error(error); + }); } }, [jumpToPage, pageId, workspaceId]); return ( diff --git a/apps/web/src/components/blocksuite/workspace-header/header-right-items/language-menu.tsx b/apps/web/src/components/blocksuite/workspace-header/header-right-items/language-menu.tsx index d0d2540724..a7001874d7 100644 --- a/apps/web/src/components/blocksuite/workspace-header/header-right-items/language-menu.tsx +++ b/apps/web/src/components/blocksuite/workspace-header/header-right-items/language-menu.tsx @@ -9,7 +9,7 @@ const LanguageMenuContent: FC = () => { const i18n = useI18N(); const changeLanguage = useCallback( (event: string) => { - i18n.changeLanguage(event); + void i18n.changeLanguage(event); }, [i18n] ); diff --git a/apps/web/src/components/blocksuite/workspace-header/header-right-items/share-menu.tsx b/apps/web/src/components/blocksuite/workspace-header/header-right-items/share-menu.tsx index 831d4a196a..b6fb02a624 100644 --- a/apps/web/src/components/blocksuite/workspace-header/header-right-items/share-menu.tsx +++ b/apps/web/src/components/blocksuite/workspace-header/header-right-items/share-menu.tsx @@ -96,8 +96,8 @@ const LocalHeaderShareMenu: React.FC = props => { onClose={() => { setOpen(false); }} - onConform={() => { - onTransformWorkspace( + onConform={async () => { + await onTransformWorkspace( WorkspaceFlavour.LOCAL, WorkspaceFlavour.AFFINE, props.workspace as LocalWorkspace diff --git a/apps/web/src/components/blocksuite/workspace-header/header-right-items/sync-user.tsx b/apps/web/src/components/blocksuite/workspace-header/header-right-items/sync-user.tsx index 605b13a4f7..cb83ec878b 100644 --- a/apps/web/src/components/blocksuite/workspace-header/header-right-items/sync-user.tsx +++ b/apps/web/src/components/blocksuite/workspace-header/header-right-items/sync-user.tsx @@ -138,17 +138,14 @@ export const SyncUser = () => { workspace as LocalWorkspace ); // fixme(himself65): refactor this - router - .replace({ - pathname: `/workspace/[workspaceId]/all`, - query: { - workspaceId: id, - }, - }) - .then(() => { - router.reload(); - }); + await router.replace({ + pathname: `/workspace/[workspaceId]/all`, + query: { + workspaceId: id, + }, + }); setOpen(false); + router.reload(); }} /> diff --git a/apps/web/src/components/blocksuite/workspace-header/header-right-items/trash-button-group.tsx b/apps/web/src/components/blocksuite/workspace-header/header-right-items/trash-button-group.tsx index e01cd71bf6..2e78760625 100644 --- a/apps/web/src/components/blocksuite/workspace-header/header-right-items/trash-button-group.tsx +++ b/apps/web/src/components/blocksuite/workspace-header/header-right-items/trash-button-group.tsx @@ -63,9 +63,10 @@ export const TrashButtonGroup = () => { workspaceId: workspace.id, }, }) - .then(() => { - blockSuiteWorkspace.removePage(pageId); + .catch(error => { + console.error(error); }); + blockSuiteWorkspace.removePage(pageId); }} onCancel={() => { setOpen(false); diff --git a/apps/web/src/components/pure/message-center/index.tsx b/apps/web/src/components/pure/message-center/index.tsx index a038adcb58..5e74a990ef 100644 --- a/apps/web/src/components/pure/message-center/index.tsx +++ b/apps/web/src/components/pure/message-center/index.tsx @@ -43,7 +43,7 @@ export const MessageCenter: FC = memo(function MessageCenter() { }) .catch(() => { setPopup(false); - onLogout(); + return onLogout(); }); } else { toast(Messages[event.detail.code].message); diff --git a/apps/web/src/components/pure/quick-search-modal/published-results.tsx b/apps/web/src/components/pure/quick-search-modal/published-results.tsx index 63d090d955..620ea0fb84 100644 --- a/apps/web/src/components/pure/quick-search-modal/published-results.tsx +++ b/apps/web/src/components/pure/quick-search-modal/published-results.tsx @@ -64,9 +64,11 @@ export const PublishedResults: FC = ({ { - router.push( - `/public-workspace/${router.query.workspaceId}/${result.id}` - ); + router + .push( + `/public-workspace/${router.query.workspaceId}/${result.id}` + ) + .catch(err => console.error(err)); onClose(); }} value={result.id} diff --git a/apps/web/src/components/pure/quick-search-modal/results.tsx b/apps/web/src/components/pure/quick-search-modal/results.tsx index a5ab439735..5bb4c22478 100644 --- a/apps/web/src/components/pure/quick-search-modal/results.tsx +++ b/apps/web/src/components/pure/quick-search-modal/results.tsx @@ -71,7 +71,9 @@ export const Results: FC = ({ value={page.id} onSelect={() => { onClose(); - jumpToPage(blockSuiteWorkspace.id, page.id); + jumpToPage(blockSuiteWorkspace.id, page.id).catch( + console.error + ); }} > @@ -95,7 +97,7 @@ export const Results: FC = ({ value={link.title} onSelect={() => { onClose(); - router.push(link.href); + router.push(link.href).catch(console.error); }} > @@ -133,7 +135,9 @@ export const Results: FC = ({ onSelect={() => { onClose(); assertExists(blockSuiteWorkspace.id); - jumpToPage(blockSuiteWorkspace.id, result.id); + jumpToPage(blockSuiteWorkspace.id, result.id).catch(error => + console.error(error) + ); }} value={result.id} > diff --git a/apps/web/src/hooks/use-workspace-blob.ts b/apps/web/src/hooks/use-workspace-blob.ts index a38d736ce1..c38a759b45 100644 --- a/apps/web/src/hooks/use-workspace-blob.ts +++ b/apps/web/src/hooks/use-workspace-blob.ts @@ -1,8 +1,11 @@ +import { DebugLogger } from '@affine/debug'; import type { BlobManager } from '@blocksuite/store'; import { useEffect, useMemo, useRef, useState } from 'react'; import type { BlockSuiteWorkspace } from '../shared'; +const logger = new DebugLogger('useWorkspaceBlob'); + export function useWorkspaceBlob( blockSuiteWorkspace: BlockSuiteWorkspace ): BlobManager { @@ -21,14 +24,19 @@ export function useWorkspaceBlobImage( setBlob(null); return; } - blobManager?.get(key).then(blob => { - if (controller.signal.aborted) { - return; - } - if (blob) { - setBlob(blob); - } - }); + blobManager + ?.get(key) + .then(blob => { + if (controller.signal.aborted) { + return; + } + if (blob) { + setBlob(blob); + } + }) + .catch(err => { + logger.error('Failed to get blob', err); + }); return () => { controller.abort(); }; diff --git a/apps/web/src/layouts/workspace-layout.tsx b/apps/web/src/layouts/workspace-layout.tsx index 0603d9450c..d0d5f29558 100644 --- a/apps/web/src/layouts/workspace-layout.tsx +++ b/apps/web/src/layouts/workspace-layout.tsx @@ -204,7 +204,9 @@ export const WorkspaceLayout: FC = useEffect(() => { document.documentElement.lang = i18n.language; // todo(himself65): this is a hack, we should use a better way to set the language - setUpLanguage(i18n); + setUpLanguage(i18n)?.catch(error => { + console.error(error); + }); }, [i18n]); useTrackRouterHistoryEffect(); const currentWorkspaceId = useAtomValue(rootCurrentWorkspaceIdAtom); @@ -247,7 +249,9 @@ export const WorkspaceLayout: FC = logger.info('mount first data:', items); } - fetch(); + fetch().catch(e => { + logger.error('fetch error:', e); + }); return () => { controller.abort(); logger.info('unmount'); diff --git a/apps/web/src/pages/404.tsx b/apps/web/src/pages/404.tsx index 6301c490c6..2631a7bb02 100644 --- a/apps/web/src/pages/404.tsx +++ b/apps/web/src/pages/404.tsx @@ -34,7 +34,7 @@ export const NotfoundPage = () => {