mirror of
https://github.com/fluencelabs/fluent-pad
synced 2025-04-25 08:52:14 +00:00
Add some nice error handling
This commit is contained in:
parent
2d8a2f8295
commit
227152a246
13
client/package-lock.json
generated
13
client/package-lock.json
generated
@ -4244,6 +4244,11 @@
|
|||||||
"shallow-clone": "^3.0.0"
|
"shallow-clone": "^3.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"clsx": {
|
||||||
|
"version": "1.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/clsx/-/clsx-1.1.1.tgz",
|
||||||
|
"integrity": "sha512-6/bPho624p3S2pMyvP5kKBPXnI3ufHLObBFCfgx+LkeR5lg2XYy2hqZqUf45ypD8COn2bhgGJSUE+l5dhNBieA=="
|
||||||
|
},
|
||||||
"co": {
|
"co": {
|
||||||
"version": "4.6.0",
|
"version": "4.6.0",
|
||||||
"resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz",
|
"resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz",
|
||||||
@ -14173,6 +14178,14 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"react-toastify": {
|
||||||
|
"version": "7.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/react-toastify/-/react-toastify-7.0.3.tgz",
|
||||||
|
"integrity": "sha512-cxZ5rfurC8LzcZQMTYc8RHIkQTs+BFur18Pzk6Loz6uS8OXUWm6nXVlH/wqglz4Z7UAE8xxcF5mRjfE13487uQ==",
|
||||||
|
"requires": {
|
||||||
|
"clsx": "^1.1.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"read-pkg": {
|
"read-pkg": {
|
||||||
"version": "1.1.0",
|
"version": "1.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz",
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
"react": "^17.0.1",
|
"react": "^17.0.1",
|
||||||
"react-dom": "^17.0.1",
|
"react-dom": "^17.0.1",
|
||||||
"react-scripts": "4.0.1",
|
"react-scripts": "4.0.1",
|
||||||
|
"react-toastify": "^7.0.3",
|
||||||
"typescript": "^4.1.3",
|
"typescript": "^4.1.3",
|
||||||
"web-vitals": "^0.2.4"
|
"web-vitals": "^0.2.4"
|
||||||
},
|
},
|
||||||
|
@ -2,11 +2,14 @@ import { createClient, FluenceClient } from '@fluencelabs/fluence';
|
|||||||
import React, { useEffect, useState } from 'react';
|
import React, { useEffect, useState } from 'react';
|
||||||
|
|
||||||
import './App.scss';
|
import './App.scss';
|
||||||
|
|
||||||
import { FluenceClientContext } from '../app/FluenceClientContext';
|
import { FluenceClientContext } from '../app/FluenceClientContext';
|
||||||
import { UserList } from './UserList';
|
import { UserList } from './UserList';
|
||||||
import * as api from 'src/app/api';
|
import * as api from 'src/app/api';
|
||||||
import { CollaborativeEditor } from './CollaborativeEditor';
|
import { CollaborativeEditor } from './CollaborativeEditor';
|
||||||
import { relayNode } from 'src/app/constants';
|
import { relayNode } from 'src/app/constants';
|
||||||
|
import { withErrorHandlingAsync } from './util';
|
||||||
|
import { toast } from 'react-toastify';
|
||||||
|
|
||||||
const App = () => {
|
const App = () => {
|
||||||
const [client, setClient] = useState<FluenceClient | null>(null);
|
const [client, setClient] = useState<FluenceClient | null>(null);
|
||||||
@ -24,8 +27,10 @@ const App = () => {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
await api.join(client, nickName);
|
await withErrorHandlingAsync(async () => {
|
||||||
setIsInRoom(true);
|
await api.join(client, nickName);
|
||||||
|
setIsInRoom(true);
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const leaveRoom = async () => {
|
const leaveRoom = async () => {
|
||||||
@ -33,8 +38,10 @@ const App = () => {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
await api.leave(client);
|
await withErrorHandlingAsync(async () => {
|
||||||
setIsInRoom(false);
|
await api.leave(client);
|
||||||
|
setIsInRoom(false);
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -6,6 +6,7 @@ import { fluentPadServiceId, notifyTextUpdateFnName } from 'src/app/constants';
|
|||||||
import { useFluenceClient } from '../app/FluenceClientContext';
|
import { useFluenceClient } from '../app/FluenceClientContext';
|
||||||
import { getUpdatedDocFromText, initDoc, SyncClient } from '../app/sync';
|
import { getUpdatedDocFromText, initDoc, SyncClient } from '../app/sync';
|
||||||
import * as api from 'src/app/api';
|
import * as api from 'src/app/api';
|
||||||
|
import { withErrorHandlingAsync } from './util';
|
||||||
|
|
||||||
const broadcastUpdates = _.debounce((text: string, syncClient: SyncClient) => {
|
const broadcastUpdates = _.debounce((text: string, syncClient: SyncClient) => {
|
||||||
let doc = syncClient.getDoc();
|
let doc = syncClient.getDoc();
|
||||||
@ -26,7 +27,9 @@ export const CollaborativeEditor = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
syncClient.handleSendChanges = (changes: string) => {
|
syncClient.handleSendChanges = (changes: string) => {
|
||||||
api.addEntry(client, changes);
|
withErrorHandlingAsync(async () => {
|
||||||
|
await api.addEntry(client, changes);
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const unsub = subscribeToEvent(client, fluentPadServiceId, notifyTextUpdateFnName, (args, tetraplets) => {
|
const unsub = subscribeToEvent(client, fluentPadServiceId, notifyTextUpdateFnName, (args, tetraplets) => {
|
||||||
@ -43,7 +46,8 @@ export const CollaborativeEditor = () => {
|
|||||||
syncClient.start();
|
syncClient.start();
|
||||||
|
|
||||||
// don't block
|
// don't block
|
||||||
api.getHistory(client).then((res) => {
|
withErrorHandlingAsync(async () => {
|
||||||
|
const res = await api.getHistory(client);
|
||||||
for (let e of res) {
|
for (let e of res) {
|
||||||
syncClient.receiveChanges(e.body);
|
syncClient.receiveChanges(e.body);
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,7 @@ import {
|
|||||||
import { useFluenceClient } from '../app/FluenceClientContext';
|
import { useFluenceClient } from '../app/FluenceClientContext';
|
||||||
import * as api from 'src/app/api';
|
import * as api from 'src/app/api';
|
||||||
import { PeerIdB58, subscribeToEvent } from '@fluencelabs/fluence';
|
import { PeerIdB58, subscribeToEvent } from '@fluencelabs/fluence';
|
||||||
|
import { withErrorHandlingAsync } from './util';
|
||||||
|
|
||||||
interface User {
|
interface User {
|
||||||
id: PeerIdB58;
|
id: PeerIdB58;
|
||||||
@ -40,7 +41,9 @@ export const UserList = (props: { selfName: string }) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// don't block
|
// don't block
|
||||||
api.updateOnlineStatuses(client);
|
withErrorHandlingAsync(async () => {
|
||||||
|
await api.updateOnlineStatuses(client);
|
||||||
|
});
|
||||||
}, refreshTimeoutMs);
|
}, refreshTimeoutMs);
|
||||||
|
|
||||||
const unsub1 = subscribeToEvent(client, fluentPadServiceId, notifyUserAddedFnName, (args, _) => {
|
const unsub1 = subscribeToEvent(client, fluentPadServiceId, notifyUserAddedFnName, (args, _) => {
|
||||||
@ -92,8 +95,10 @@ export const UserList = (props: { selfName: string }) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// don't block
|
// don't block
|
||||||
api.getUserList(client);
|
withErrorHandlingAsync(async () => {
|
||||||
api.notifySelfAdded(client, props.selfName);
|
await api.getUserList(client);
|
||||||
|
await api.notifySelfAdded(client, props.selfName);
|
||||||
|
});
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
clearTimeout(listRefreshTimer);
|
clearTimeout(listRefreshTimer);
|
||||||
|
19
client/src/components/util.tsx
Normal file
19
client/src/components/util.tsx
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
import { toast } from 'react-toastify';
|
||||||
|
|
||||||
|
export const withErrorHandling = (fn: () => void): void => {
|
||||||
|
try {
|
||||||
|
fn();
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err);
|
||||||
|
toast.error('Something went wrong: ' + err);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export const withErrorHandlingAsync = async (fn: () => Promise<void>): Promise<void> => {
|
||||||
|
try {
|
||||||
|
await fn();
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err);
|
||||||
|
toast.error('Something went wrong: ' + err);
|
||||||
|
}
|
||||||
|
};
|
@ -2,14 +2,18 @@ import React from 'react';
|
|||||||
import ReactDOM from 'react-dom';
|
import ReactDOM from 'react-dom';
|
||||||
import './index.scss';
|
import './index.scss';
|
||||||
import App from './components/App';
|
import App from './components/App';
|
||||||
import log from 'loglevel';
|
import { setLogLevel } from '@fluencelabs/fluence';
|
||||||
|
import { ToastContainer } from 'react-toastify';
|
||||||
|
import 'react-toastify/dist/ReactToastify.css';
|
||||||
|
|
||||||
// log.setLevel('trace');
|
setLogLevel('INFO');
|
||||||
log.setLevel('error');
|
|
||||||
|
|
||||||
ReactDOM.render(
|
ReactDOM.render(
|
||||||
<React.StrictMode>
|
<React.StrictMode>
|
||||||
<App />
|
<div>
|
||||||
|
<App />
|
||||||
|
<ToastContainer />
|
||||||
|
</div>
|
||||||
</React.StrictMode>,
|
</React.StrictMode>,
|
||||||
document.getElementById('root'),
|
document.getElementById('root'),
|
||||||
);
|
);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user