cetirizine

An experimental matrix client written in reactjs utilizing tailwind and storybook
git clone git://archive.git.mtrnord.blog/MTRNord/cetirizine.git
Log | Files | Refs | README | LICENSE

commit 3081db8ce62670475ed897bc4bb9e5b7e034a29a
parent 7ba3f2f76e07582a538d6b5963d05a6c4ee02319
Author: MTRNord <mtrnord1@gmail.com>
Date:   Tue, 19 Sep 2023 11:03:31 +0200

Rework error handling

Diffstat:
Msrc/app/sdk/client.ts | 9+++------
Msrc/app/sdk/e2ee.ts | 55++++++++++++++++++++-----------------------------------
Msrc/app/sdk/ownUser.ts | 13+++++--------
Msrc/app/sdk/slidingSync.ts | 18++++++------------
Dsrc/app/sdk/testUtil.ts | 5-----
Asrc/app/sdk/utils.ts | 28++++++++++++++++++++++++++++
Msrc/pages/MainPage.tsx | 13+++++++++++++
7 files changed, 75 insertions(+), 66 deletions(-)

diff --git a/src/app/sdk/client.ts b/src/app/sdk/client.ts @@ -20,7 +20,7 @@ import { } from "idb"; import { DeviceId, UserId } from "@mtrnord/matrix-sdk-crypto-js"; import { MatrixSlidingSync } from "./slidingSync"; -import { isTesting } from './testUtil'; +import { NotLogeedInError, SDKError } from './utils'; export interface MatrixClientEvents { // Used to notify about changes to the room list @@ -233,12 +233,9 @@ export class MatrixClient extends EventEmitter { }); } - public async decryptRoomEvent(roomID: string, event: IRoomEvent): Promise<IRoomEvent> { + public async decryptRoomEvent(roomID: string, event: IRoomEvent): Promise<SDKError | IRoomEvent> { if (!this.isLoggedIn) { - if (isTesting()) { - return { content: {}, event_id: "", type: "", sender: "", origin_server_ts: 0 }; - } - throw Error("Not logged in"); + return new NotLogeedInError(); } const decryptedEvent = this.user.e2ee.decryptRoomEvent(roomID, event); return decryptedEvent; diff --git a/src/app/sdk/e2ee.ts b/src/app/sdk/e2ee.ts @@ -17,7 +17,7 @@ import { MatrixClient } from "./client"; import { OwnUser } from "./ownUser"; import { Room } from "./room"; import { IRoomEvent } from "./api/events"; -import { isTesting } from "./testUtil"; +import { HostnameMissingError, NotLogeedInError, OlmMachineNotSetup, SDKError } from "./utils"; export class MatrixE2EE { private olmMachine?: OlmMachine; @@ -44,15 +44,12 @@ export class MatrixE2EE { ); } - public async encryptRoomEvent(roomID: RoomId, type: string, content: string): Promise<any> { + public async encryptRoomEvent(roomID: RoomId, type: string, content: string): Promise<SDKError | any> { if (!this.client.isLoggedIn) { - if (isTesting()) { - return null; - } - throw Error("Not logged in"); + return new NotLogeedInError(); } if (!this.olmMachine) { - throw Error("Olm machine must be set first"); + return new OlmMachineNotSetup(); } return await this.olmMachine?.encryptRoomEvent(roomID, type, content); } @@ -66,18 +63,15 @@ export class MatrixE2EE { await this.olmMachine?.updateTrackedUsers(users); } - public async sendIdentifyAndOneTimeKeys(): Promise<void> { + public async sendIdentifyAndOneTimeKeys(): Promise<SDKError | void> { if (!this.client.isLoggedIn) { - if (isTesting()) { - return; - } - throw Error("Not logged in"); + return new NotLogeedInError(); } if (!this.user.hostname) { - throw Error("Hostname must be set first"); + return new HostnameMissingError(); } if (!this.olmMachine) { - throw Error("Olm machine must be set first"); + return new OlmMachineNotSetup(); } if (this.outgoingRequestsBeingProcessed) { @@ -95,18 +89,15 @@ export class MatrixE2EE { this.outgoingRequestsBeingProcessed = false; } - public async shareKeysForRoom(room: Room): Promise<void> { + public async shareKeysForRoom(room: Room): Promise<SDKError | void> { if (!this.client.isLoggedIn) { - if (isTesting()) { - return; - } - throw Error("Not logged in"); + return new NotLogeedInError(); } if (!this.user.hostname) { - throw Error("Hostname must be set first"); + return new HostnameMissingError(); } if (!this.olmMachine) { - throw Error("Olm machine must be set first"); + return new OlmMachineNotSetup(); } const encryptionSettings = room.getEncryptionSettings(); if (encryptionSettings) { @@ -117,18 +108,15 @@ export class MatrixE2EE { } } - public async getMissingSessions(): Promise<void> { + public async getMissingSessions(): Promise<SDKError | void> { if (!this.client.isLoggedIn) { - if (isTesting()) { - return; - } - throw Error("Not logged in"); + return new NotLogeedInError(); } if (!this.user.hostname) { - throw Error("Hostname must be set first"); + return new HostnameMissingError(); } if (!this.olmMachine) { - throw Error("Olm machine must be set first"); + return new OlmMachineNotSetup(); } if (this.missingSessionsBeingRequested) { @@ -146,18 +134,15 @@ export class MatrixE2EE { this.missingSessionsBeingRequested = false; } - private async processRequest(request: any): Promise<void> { + private async processRequest(request: any): Promise<SDKError | void> { if (!this.client.isLoggedIn) { - if (isTesting()) { - return; - } - throw Error("Not logged in"); + return new NotLogeedInError(); } if (!this.user.hostname) { - throw Error("Hostname must be set first"); + return new HostnameMissingError(); } if (!this.olmMachine) { - throw Error("Olm machine must be set first"); + return new OlmMachineNotSetup(); } // Check which type the request is if (request.type === RequestType.KeysUpload) { diff --git a/src/app/sdk/ownUser.ts b/src/app/sdk/ownUser.ts @@ -2,7 +2,7 @@ import { DeviceId, UserId } from "@mtrnord/matrix-sdk-crypto-js"; import { IErrorResp, ILoginFlows, ILoginResponse, IWellKnown } from "./api/apiTypes"; import { MatrixClient, isRateLimitError } from "./client"; import { MatrixE2EE } from "./e2ee"; -import { isTesting } from "./testUtil"; +import { HostnameMissingError, NotLogeedInError, SDKError } from "./utils"; export class OwnUser { public access_token?: string; @@ -18,18 +18,15 @@ export class OwnUser { } // TODO: call logout endpoint on logout - public async logout() { + public async logout(): Promise<void | SDKError> { if (!this.mxid) { - if (isTesting()) { - return; - } - throw Error("Not logged in"); + return new NotLogeedInError(); } if (!this.access_token) { - throw Error("Not logged in"); + return new NotLogeedInError(); } if (!this.hostname) { - throw Error("Hostname must be set first"); + return new HostnameMissingError(); } const resp = await fetch(`${this.hostname}/_matrix/client/v3/logout`, { method: "POST", diff --git a/src/app/sdk/slidingSync.ts b/src/app/sdk/slidingSync.ts @@ -5,7 +5,7 @@ import { Room } from "./room"; import { OwnUser } from "./ownUser"; import { DeviceLists, UserId } from "@mtrnord/matrix-sdk-crypto-js"; import { IRoomEvent, IRoomStateEvent, isRoomStateEvent } from "./api/events"; -import { isTesting } from "./testUtil"; +import { HostnameMissingError, NotLogeedInError, SDKError } from "./utils"; export interface MatrixSlidingSyncEvents { // Used to notify about changes to the room list @@ -66,16 +66,13 @@ export class MatrixSlidingSync extends EventEmitter { this.abortController = new AbortController(); } - public async startSync() { + public async startSync(): Promise<SDKError | void> { // @ts-ignore if (globalThis.IS_STORYBOOK) { await new Promise(r => setTimeout(r, 5000)); } if (!this.client.isLoggedIn) { - if (isTesting()) { - return; - } - throw Error("Not logged in"); + return new NotLogeedInError(); } if (!this.client.database) { await this.client.createDatabase(); @@ -185,15 +182,12 @@ export class MatrixSlidingSync extends EventEmitter { this.shiftRight(listKey, ranges, max + 1, index); } - private async sync() { + private async sync(): Promise<SDKError | void> { if (!this.client.isLoggedIn) { - if (isTesting()) { - return; - } - throw Error("Not logged in"); + return new NotLogeedInError(); } if (!this.user.slidingSyncHostname) { - throw Error("Hostname must be set first"); + return new HostnameMissingError(); } // TODO: This might cause future issues diff --git a/src/app/sdk/testUtil.ts b/src/app/sdk/testUtil.ts @@ -1,4 +0,0 @@ -/// This checks for jest and disables the not logged in throws and uses returns instead -export function isTesting(): boolean { - return typeof jest !== 'undefined' -} -\ No newline at end of file diff --git a/src/app/sdk/utils.ts b/src/app/sdk/utils.ts @@ -0,0 +1,27 @@ +export class SDKError extends Error { + protected constructor(msg?: string) { + if (msg) { + super(msg) + } else { + super("The Matrix SDK encountered and unknown error") + } + } +} + +export class NotLogeedInError extends SDKError { + constructor() { + super("Not logged in") + } +} + +export class HostnameMissingError extends SDKError { + constructor() { + super("Hostname must be set first") + } +} + +export class OlmMachineNotSetup extends SDKError { + constructor() { + super("Olm machine must be set first") + } +} +\ No newline at end of file diff --git a/src/pages/MainPage.tsx b/src/pages/MainPage.tsx @@ -16,6 +16,7 @@ import Linkify from 'linkify-react'; import { OnlineState } from '../app/sdk/api/otherEnums'; import { Virtuoso } from 'react-virtuoso'; import ReactModal from 'react-modal'; +import { SDKError } from '../app/sdk/utils'; type ChatViewProps = { /** @@ -59,6 +60,18 @@ const ChatView: FC<ChatViewProps> = memo(({ room, id }) => { if (event.type === "m.room.encrypted" && room?.roomID) { try { const decrypted_event = await client.decryptRoomEvent(room.roomID, event); + if (decrypted_event instanceof SDKError) { + // TODO: Show proper error instead + return { + ...event, + unsigned: { + ...event.unsigned, + undecryptable: true, + key: event.event_id, + hasPreviousEvent: previousEventIsFromSameSender + } + } + } if (decrypted_event) { event = JSON.parse(decrypted_event.event) as IRoomEvent; if (event.content["m.new_content"]) {