From 9ae9bb8092f9e050c7332ba827adf596f6166c9c Mon Sep 17 00:00:00 2001 From: MingLiang Wang Date: Thu, 12 Jan 2023 15:11:49 +0800 Subject: [PATCH] feat: add affine request error msg --- packages/data-center/src/datacenter.ts | 2 +- packages/data-center/src/message/code.ts | 58 ++++++++ packages/data-center/src/message/message.ts | 32 +++-- .../data-center/src/provider/affine/affine.ts | 25 ++-- .../src/provider/affine/apis/request.ts | 16 ++- .../src/provider/affine/apis/workspace.ts | 133 +++++++++++++----- packages/data-center/src/provider/base.ts | 9 +- .../data-center/src/provider/local/local.ts | 2 +- packages/data-center/src/types/index.ts | 1 + 9 files changed, 217 insertions(+), 61 deletions(-) diff --git a/packages/data-center/src/datacenter.ts b/packages/data-center/src/datacenter.ts index 0e6dee8271..551fa009cf 100644 --- a/packages/data-center/src/datacenter.ts +++ b/packages/data-center/src/datacenter.ts @@ -23,7 +23,7 @@ export class DataCenter { private readonly _workspaceUnitCollection = new WorkspaceUnitCollection(); private readonly _logger = getLogger('dc'); private _workspaceInstances: Map = new Map(); - private _messageCenter = new MessageCenter(); + private _messageCenter = MessageCenter.getInstance(); /** * A mainProvider must exist as the only data trustworthy source. */ diff --git a/packages/data-center/src/message/code.ts b/packages/data-center/src/message/code.ts index 271ffc8d38..d7df926960 100644 --- a/packages/data-center/src/message/code.ts +++ b/packages/data-center/src/message/code.ts @@ -1,3 +1,61 @@ export enum MessageCode { loginError, + noPermission, + loadListFailed, + getDetailFailed, + createWorkspaceFailed, + getMembersFailed, + updateWorkspaceFailed, + deleteWorkspaceFailed, + inviteMemberFailed, + removeMemberFailed, + acceptInvitingFailed, + getBlobFailed, + leaveWorkspaceFailed, + downloadWorkspaceFailed, } + +export const messages = { + [MessageCode.loginError]: { + message: 'Login failed', + }, + [MessageCode.noPermission]: { + message: 'No permission', + }, + [MessageCode.loadListFailed]: { + message: 'Load list failed', + }, + [MessageCode.getDetailFailed]: { + message: 'Get detail failed', + }, + [MessageCode.createWorkspaceFailed]: { + message: 'Create workspace failed', + }, + [MessageCode.getMembersFailed]: { + message: 'Get members failed', + }, + [MessageCode.updateWorkspaceFailed]: { + message: 'Update workspace failed', + }, + [MessageCode.deleteWorkspaceFailed]: { + message: 'Delete workspace failed', + }, + [MessageCode.inviteMemberFailed]: { + message: 'Invite member failed', + }, + [MessageCode.removeMemberFailed]: { + message: 'Remove member failed', + }, + [MessageCode.acceptInvitingFailed]: { + message: 'Accept inviting failed', + }, + [MessageCode.getBlobFailed]: { + message: 'Get blob failed', + }, + [MessageCode.leaveWorkspaceFailed]: { + message: 'Leave workspace failed', + }, + [MessageCode.downloadWorkspaceFailed]: { + message: 'Download workspace failed', + }, +}; diff --git a/packages/data-center/src/message/message.ts b/packages/data-center/src/message/message.ts index 6de9c75795..4becebc2ff 100644 --- a/packages/data-center/src/message/message.ts +++ b/packages/data-center/src/message/message.ts @@ -1,24 +1,36 @@ import { Observable } from 'lib0/observable'; import { Message } from '../types'; -import { MessageCode } from './code.js'; +import { MessageCode, messages } from './code.js'; export class MessageCenter extends Observable { + private _messages: Record> = + messages; constructor() { super(); } - public send(message: MessageCode) { - this.emit('message', [message]); + static instance: MessageCenter; + + static getInstance() { + if (!MessageCenter.instance) { + MessageCenter.instance = new MessageCenter(); + } + return MessageCenter.instance; + } + + static messageCode = MessageCode; + + public getMessageSender(provider: string) { + return this._send.bind(this, provider); + } + + private _send(provider: string, messageCode: MessageCode) { + this.emit('message', [ + { ...this._messages[messageCode], provider, code: messageCode }, + ]); } public onMessage(callback: (message: Message) => void) { this.on('message', callback); } - - private messages: Record = { - [MessageCode.loginError]: { - code: MessageCode.loginError, - message: 'Login failed', - }, - }; } diff --git a/packages/data-center/src/provider/affine/affine.ts b/packages/data-center/src/provider/affine/affine.ts index 5abb451e62..d4c4027772 100644 --- a/packages/data-center/src/provider/affine/affine.ts +++ b/packages/data-center/src/provider/affine/affine.ts @@ -2,7 +2,6 @@ import { BaseProvider } from '../base.js'; import type { ProviderConstructorParams, CreateWorkspaceInfoParams, - WorkspaceMeta0, } from '../base'; import type { User } from '../../types'; import { Workspace as BlocksuiteWorkspace } from '@blocksuite/store'; @@ -12,8 +11,6 @@ import { WebsocketProvider } from './sync.js'; // import { IndexedDBProvider } from '../local/indexeddb'; import { getApis, Workspace } from './apis/index.js'; import type { Apis, WorkspaceDetail, Callback } from './apis'; -import { setDefaultAvatar } from '../utils.js'; -import { MessageCode } from '../../message/index.js'; import { token } from './apis/token.js'; import { WebsocketClient } from './channel'; import { @@ -24,6 +21,7 @@ import { import { WorkspaceUnit } from '../../workspace-unit.js'; import { createBlocksuiteWorkspace, applyUpdate } from '../../utils/index.js'; import type { SyncMode } from '../../workspace-unit'; +import { MessageCenter } from 'src/message/message.js'; type ChannelMessage = { ws_list: Workspace[]; @@ -42,7 +40,6 @@ const { export class AffineProvider extends BaseProvider { public id = 'affine'; - private _workspacesCache: Map = new Map(); private _onTokenRefresh?: Callback = undefined; private _wsMap: Map = new Map(); private _apis: Apis; @@ -121,7 +118,7 @@ export class AffineProvider extends BaseProvider { }, published: detail.public, memberCount: detail.member_count, - provider: 'affine', + provider: this.id, syncMode: 'core' as SyncMode, }; if (this._workspaces.get(id)) { @@ -207,7 +204,7 @@ export class AffineProvider extends BaseProvider { owner: undefined, published: w.public, memberCount: 1, - provider: 'affine', + provider: this.id, syncMode: 'core', }, this._apis @@ -232,7 +229,7 @@ export class AffineProvider extends BaseProvider { this._connectChannel(); } if (!user) { - this._messageCenter.send(MessageCode.loginError); + this._sendMessage(MessageCenter.messageCode.loginError); } } @@ -257,17 +254,17 @@ export class AffineProvider extends BaseProvider { } public override async clear(): Promise { - for (const w of this._workspacesCache.values()) { - if (w.room) { + for (const w of this._workspaces.list()) { + if (w.id) { try { - await this.deleteWorkspace(w.room); - this._workspaces.remove(w.room); + await this.deleteWorkspace(w.id); + this._workspaces.remove(w.id); } catch (e) { this._logger('has a problem of delete workspace ', e); } } } - this._workspacesCache.clear(); + this._workspaces.clear(); } public override async closeWorkspace(id: string) { @@ -313,7 +310,7 @@ export class AffineProvider extends BaseProvider { owner: await this.getUserInfo(), published: false, memberCount: 1, - provider: 'affine', + provider: this.id, syncMode: 'core', }); @@ -358,7 +355,7 @@ export class AffineProvider extends BaseProvider { owner: await this.getUserInfo(), published: false, memberCount: 1, - provider: 'affine', + provider: this.id, syncMode: 'core', }); diff --git a/packages/data-center/src/provider/affine/apis/request.ts b/packages/data-center/src/provider/affine/apis/request.ts index ce5b64eebe..2520b1d535 100644 --- a/packages/data-center/src/provider/affine/apis/request.ts +++ b/packages/data-center/src/provider/affine/apis/request.ts @@ -1,7 +1,11 @@ -import kyOrigin from 'ky'; import ky from 'ky-universal'; +import { MessageCenter } from '../../../message/index.js'; import { token } from './token.js'; +const messageCenter = MessageCenter.getInstance(); + +const _sendMessage = messageCenter.getMessageSender('affine'); + export const bareClient = ky.extend({ prefixUrl: 'http://localhost:8080', retry: 1, @@ -41,5 +45,15 @@ export const client = bareClient.extend({ request.headers.set('Authorization', token.token); }, ], + + beforeError: [ + error => { + const { response } = error; + if (response.status === 401) { + _sendMessage(MessageCenter.messageCode.noPermission); + } + return error; + }, + ], }, }); diff --git a/packages/data-center/src/provider/affine/apis/workspace.ts b/packages/data-center/src/provider/affine/apis/workspace.ts index 6151946660..0ac62a203f 100644 --- a/packages/data-center/src/provider/affine/apis/workspace.ts +++ b/packages/data-center/src/provider/affine/apis/workspace.ts @@ -1,6 +1,19 @@ +import { MessageCenter } from 'src/message/message.js'; import { bareClient, client } from './request.js'; import type { User } from './user'; +const messageCenter = MessageCenter.getInstance(); + +const sendMessage = messageCenter.getMessageSender('affine'); + +const { messageCode } = MessageCenter; + +class RequestError extends Error { + constructor(message: string) { + super(message); + this.name = 'RequestError'; + } +} export interface GetWorkspaceDetailParams { id: string; } @@ -26,13 +39,18 @@ export interface Workspace { } export async function getWorkspaces(): Promise { - return client - .get('api/workspace', { - headers: { - 'Cache-Control': 'no-cache', - }, - }) - .json(); + try { + return client + .get('api/workspace', { + headers: { + 'Cache-Control': 'no-cache', + }, + }) + .json(); + } catch (error) { + sendMessage(messageCode.loadListFailed); + throw new RequestError('load list failed'); + } } export interface WorkspaceDetail extends Workspace { @@ -43,7 +61,13 @@ export interface WorkspaceDetail extends Workspace { export async function getWorkspaceDetail( params: GetWorkspaceDetailParams ): Promise { - return client.get(`api/workspace/${params.id}`).json(); + try { + const response = client.get(`api/workspace/${params.id}`); + return response.json(); + } catch (error) { + sendMessage(messageCode.getDetailFailed); + throw new RequestError('get detail failed'); + } } export interface Permission { @@ -74,7 +98,12 @@ export interface GetWorkspaceMembersParams { export async function getWorkspaceMembers( params: GetWorkspaceDetailParams ): Promise { - return client.get(`api/workspace/${params.id}/permission`).json(); + try { + return client.get(`api/workspace/${params.id}/permission`).json(); + } catch (error) { + sendMessage(messageCode.getMembersFailed); + throw new RequestError('get members failed'); + } } export interface CreateWorkspaceParams { @@ -84,7 +113,12 @@ export interface CreateWorkspaceParams { export async function createWorkspace( params: CreateWorkspaceParams ): Promise<{ id: string }> { - return client.post('api/workspace', { json: params }).json(); + try { + return client.post('api/workspace', { json: params }).json(); + } catch (error) { + sendMessage(messageCode.createWorkspaceFailed); + throw new RequestError('create workspace failed'); + } } export interface UpdateWorkspaceParams { @@ -95,13 +129,18 @@ export interface UpdateWorkspaceParams { export async function updateWorkspace( params: UpdateWorkspaceParams ): Promise<{ public: boolean | null }> { - return client - .post(`api/workspace/${params.id}`, { - json: { - public: params.public, - }, - }) - .json(); + try { + return client + .post(`api/workspace/${params.id}`, { + json: { + public: params.public, + }, + }) + .json(); + } catch (error) { + sendMessage(messageCode.updateWorkspaceFailed); + throw new RequestError('update workspace failed'); + } } export interface DeleteWorkspaceParams { @@ -111,7 +150,10 @@ export interface DeleteWorkspaceParams { export async function deleteWorkspace( params: DeleteWorkspaceParams ): Promise { - await client.delete(`api/workspace/${params.id}`); + await client.delete(`api/workspace/${params.id}`).catch(() => { + sendMessage(messageCode.deleteWorkspaceFailed); + throw new RequestError('delete workspace failed'); + }); } export interface InviteMemberParams { @@ -123,13 +165,18 @@ export interface InviteMemberParams { * Notice: Only support normal(contrast to private) workspace. */ export async function inviteMember(params: InviteMemberParams): Promise { - return client - .post(`api/workspace/${params.id}/permission`, { - json: { - email: params.email, - }, - }) - .json(); + try { + return client + .post(`api/workspace/${params.id}/permission`, { + json: { + email: params.email, + }, + }) + .json(); + } catch (error) { + sendMessage(messageCode.inviteMemberFailed); + throw new RequestError('invite member failed'); + } } export interface RemoveMemberParams { @@ -137,7 +184,10 @@ export interface RemoveMemberParams { } export async function removeMember(params: RemoveMemberParams): Promise { - await client.delete(`api/permission/${params.permissionId}`); + await client.delete(`api/permission/${params.permissionId}`).catch(() => { + sendMessage(messageCode.removeMemberFailed); + throw new RequestError('remove member failed'); + }); } export interface AcceptInvitingParams { @@ -147,7 +197,10 @@ export interface AcceptInvitingParams { export async function acceptInviting( params: AcceptInvitingParams ): Promise { - await bareClient.post(`api/invitation/${params.invitingCode}`); + await bareClient.post(`api/invitation/${params.invitingCode}`).catch(() => { + sendMessage(messageCode.acceptInvitingFailed); + throw new RequestError('accept inviting failed'); + }); } export async function uploadBlob(params: { blob: Blob }): Promise { @@ -157,7 +210,12 @@ export async function uploadBlob(params: { blob: Blob }): Promise { export async function getBlob(params: { blobId: string; }): Promise { - return client.get(`api/blob/${params.blobId}`).arrayBuffer(); + try { + return client.get(`api/blob/${params.blobId}`).arrayBuffer(); + } catch (error) { + sendMessage(messageCode.getBlobFailed); + throw new RequestError('get blob failed'); + } } export interface LeaveWorkspaceParams { @@ -165,15 +223,26 @@ export interface LeaveWorkspaceParams { } export async function leaveWorkspace({ id }: LeaveWorkspaceParams) { - await client.delete(`api/workspace/${id}/permission`).json(); + await client + .delete(`api/workspace/${id}/permission`) + .json() + .catch(() => { + sendMessage(messageCode.leaveWorkspaceFailed); + throw new RequestError('leave workspace failed'); + }); } export async function downloadWorkspace( workspaceId: string, published = false ): Promise { - if (published) { - return bareClient.get(`api/workspace/${workspaceId}/doc`).arrayBuffer(); + try { + if (published) { + return bareClient.get(`api/workspace/${workspaceId}/doc`).arrayBuffer(); + } + return client.get(`api/workspace/${workspaceId}/doc`).arrayBuffer(); + } catch (error) { + sendMessage(messageCode.downloadWorkspaceFailed); + throw new RequestError('download workspace failed'); } - return client.get(`api/workspace/${workspaceId}/doc`).arrayBuffer(); } diff --git a/packages/data-center/src/provider/base.ts b/packages/data-center/src/provider/base.ts index 653efb6bc6..0f0a23ead3 100644 --- a/packages/data-center/src/provider/base.ts +++ b/packages/data-center/src/provider/base.ts @@ -22,10 +22,15 @@ export type UpdateWorkspaceMetaParams = Partial< >; export class BaseProvider { + /** provider id */ public readonly id: string = 'base'; + /** workspace unit collection */ protected _workspaces!: WorkspaceUnitCollectionScope; protected _logger!: Logger; - protected _messageCenter!: MessageCenter; + /** send message with message center */ + protected _sendMessage!: ReturnType< + InstanceType['getMessageSender'] + >; public constructor({ logger, @@ -34,7 +39,7 @@ export class BaseProvider { }: ProviderConstructorParams) { this._logger = (logger || defaultLogger) as Logger; this._workspaces = workspaces; - this._messageCenter = messageCenter; + this._sendMessage = messageCenter.getMessageSender(this.id); } /** diff --git a/packages/data-center/src/provider/local/local.ts b/packages/data-center/src/provider/local/local.ts index ad71943067..4ceb2a7a73 100644 --- a/packages/data-center/src/provider/local/local.ts +++ b/packages/data-center/src/provider/local/local.ts @@ -100,7 +100,7 @@ export class LocalProvider extends BaseProvider { owner: undefined, syncMode: 'core', memberCount: 1, - provider: 'local', + provider: this.id, }); this._workspaces.add(workspaceUnit); this._storeWorkspaces(this._workspaces.list()); diff --git a/packages/data-center/src/types/index.ts b/packages/data-center/src/types/index.ts index ea85ded82f..33343f939f 100644 --- a/packages/data-center/src/types/index.ts +++ b/packages/data-center/src/types/index.ts @@ -25,4 +25,5 @@ export type Logger = ReturnType; export type Message = { code: number; message: string; + provider: string; };