feat(workspace): handle error on apis (#1700)

This commit is contained in:
Himself65 2023-03-27 15:25:30 -05:00 committed by GitHub
parent 628ce08d8d
commit 021bf6534b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 117 additions and 15 deletions

View File

@ -3,12 +3,17 @@
*/
import 'fake-indexeddb/auto';
import { MessageCode } from '@affine/datacenter';
import userA from '@affine-test/fixtures/userA.json';
import { assertExists } from '@blocksuite/global/utils';
import { Workspace } from '@blocksuite/store';
import { beforeAll, beforeEach, describe, expect, test } from 'vitest';
import { beforeEach, describe, expect, test, vi } from 'vitest';
import { createWorkspaceApis, createWorkspaceResponseSchema } from '../api';
import {
createWorkspaceApis,
createWorkspaceResponseSchema,
RequestError,
} from '../api';
import {
createAffineAuth,
getLoginStorage,
@ -19,7 +24,7 @@ import {
let workspaceApis: ReturnType<typeof createWorkspaceApis>;
let affineAuth: ReturnType<typeof createAffineAuth>;
beforeAll(() => {
beforeEach(() => {
affineAuth = createAffineAuth('http://localhost:3000/');
workspaceApis = createWorkspaceApis('http://localhost:3000/');
});
@ -56,7 +61,36 @@ beforeEach(async () => {
loginResponseSchema.parse(data);
});
declare global {
interface DocumentEventMap {
'affine-error': CustomEvent<{
code: MessageCode;
}>;
}
}
describe('api', () => {
test('failed', async () => {
workspaceApis = createWorkspaceApis('http://localhost:10086/404/');
const listener = vi.fn(
(
e: CustomEvent<{
code: MessageCode;
}>
) => {
expect(e.detail.code).toBe(MessageCode.loadListFailed);
}
);
document.addEventListener('affine-error', listener);
expect(listener).toBeCalledTimes(0);
await workspaceApis.getWorkspaces().catch(e => {
expect(e).toBeInstanceOf(RequestError);
});
expect(listener).toBeCalledTimes(1);
document.removeEventListener('affine-error', listener);
});
test('refresh token', async () => {
const storage = getLoginStorage();
assertExists(storage);

View File

@ -1,8 +1,28 @@
import { MessageCode, Messages } from '@affine/env';
import { assertExists } from '@blocksuite/global/utils';
import { z } from 'zod';
import { getLoginStorage } from '../login';
export class RequestError extends Error {
constructor(code: MessageCode, cause: unknown | null = null) {
super(Messages[code].message);
sendMessage(code);
this.name = 'RequestError';
this.cause = cause;
}
}
function sendMessage(code: MessageCode) {
document.dispatchEvent(
new CustomEvent('affine-error', {
detail: {
code,
},
})
);
}
export interface User {
id: string;
name: string;
@ -139,7 +159,11 @@ export function createWorkspaceApis(prefixUrl = '/') {
Authorization: auth.token,
'Cache-Control': 'no-cache',
},
}).then(r => r.json());
})
.then(r => r.json())
.catch(e => {
throw new RequestError(MessageCode.loadListFailed, e);
});
},
getWorkspaceDetail: async (
params: GetWorkspaceDetailParams
@ -151,7 +175,11 @@ export function createWorkspaceApis(prefixUrl = '/') {
headers: {
Authorization: auth.token,
},
}).then(r => r.json());
})
.then(r => r.json())
.catch(e => {
throw new RequestError(MessageCode.loadListFailed, e);
});
},
getWorkspaceMembers: async (
params: GetWorkspaceDetailParams
@ -163,7 +191,11 @@ export function createWorkspaceApis(prefixUrl = '/') {
headers: {
Authorization: auth.token,
},
}).then(r => r.json());
})
.then(r => r.json())
.catch(e => {
throw new RequestError(MessageCode.getMembersFailed, e);
});
},
createWorkspace: async (encodedYDoc: Blob): Promise<{ id: string }> => {
const auth = getLoginStorage();
@ -174,7 +206,11 @@ export function createWorkspaceApis(prefixUrl = '/') {
headers: {
Authorization: auth.token,
},
}).then(r => r.json());
})
.then(r => r.json())
.catch(e => {
throw new RequestError(MessageCode.createWorkspaceFailed, e);
});
},
updateWorkspace: async (
params: UpdateWorkspaceParams
@ -190,7 +226,11 @@ export function createWorkspaceApis(prefixUrl = '/') {
'Content-Type': 'application/json',
Authorization: auth.token,
},
}).then(r => r.json());
})
.then(r => r.json())
.catch(e => {
throw new RequestError(MessageCode.updateWorkspaceFailed, e);
});
},
deleteWorkspace: async (
params: DeleteWorkspaceParams
@ -202,7 +242,11 @@ export function createWorkspaceApis(prefixUrl = '/') {
headers: {
Authorization: auth.token,
},
}).then(r => r.ok);
})
.then(r => r.ok)
.catch(e => {
throw new RequestError(MessageCode.deleteWorkspaceFailed, e);
});
},
/**
@ -220,7 +264,11 @@ export function createWorkspaceApis(prefixUrl = '/') {
'Content-Type': 'application/json',
Authorization: auth.token,
},
}).then(r => r.json());
})
.then(r => r.json())
.catch(e => {
throw new RequestError(MessageCode.inviteMemberFailed, e);
});
},
removeMember: async (params: RemoveMemberParams): Promise<void> => {
const auth = getLoginStorage();
@ -230,14 +278,22 @@ export function createWorkspaceApis(prefixUrl = '/') {
headers: {
Authorization: auth.token,
},
}).then(r => r.json());
})
.then(r => r.json())
.catch(e => {
throw new RequestError(MessageCode.removeMemberFailed, e);
});
},
acceptInviting: async (
params: AcceptInvitingParams
): Promise<Permission> => {
return fetch(prefixUrl + `api/invitation/${params.invitingCode}`, {
method: 'POST',
}).then(r => r.json());
})
.then(r => r.json())
.catch(e => {
throw new RequestError(MessageCode.acceptInvitingFailed, e);
});
},
uploadBlob: async (params: { blob: Blob }): Promise<string> => {
const auth = getLoginStorage();
@ -258,7 +314,11 @@ export function createWorkspaceApis(prefixUrl = '/') {
headers: {
Authorization: auth.token,
},
}).then(r => r.arrayBuffer());
})
.then(r => r.arrayBuffer())
.catch(e => {
throw new RequestError(MessageCode.getBlobFailed, e);
});
},
leaveWorkspace: async ({ id }: LeaveWorkspaceParams) => {
const auth = getLoginStorage();
@ -268,7 +328,11 @@ export function createWorkspaceApis(prefixUrl = '/') {
headers: {
Authorization: auth.token,
},
}).then(r => r.json());
})
.then(r => r.json())
.catch(e => {
throw new RequestError(MessageCode.leaveWorkspaceFailed, e);
});
},
downloadWorkspace: async (
workspaceId: string,
@ -286,7 +350,11 @@ export function createWorkspaceApis(prefixUrl = '/') {
headers: {
Authorization: auth.token,
},
}).then(r => r.arrayBuffer());
})
.then(r => r.arrayBuffer())
.catch(e => {
throw new RequestError(MessageCode.downloadWorkspaceFailed, e);
});
}
},
} as const;