Improve error handling: failing to parse items/collections + syncmanager
parent
74f4409f56
commit
b8442532e8
|
@ -46,10 +46,8 @@ export default function CalendarsMain() {
|
|||
}
|
||||
(async () => {
|
||||
const colEntries = await decryptCollections(collections);
|
||||
// FIXME: handle failure to decrypt collections
|
||||
|
||||
const entries = await decryptItems(items);
|
||||
// FIXME: handle failure to decrypt items
|
||||
|
||||
for (const collection of colEntries) {
|
||||
const items = entries.get(collection.collection.uid)!;
|
||||
|
|
|
@ -66,7 +66,6 @@ export default function CollectionChangeEntries(props: PropsType) {
|
|||
if (items) {
|
||||
decryptItems(items)
|
||||
.then((entries) => setEntries(entries.get(collection.uid)));
|
||||
// FIXME: handle failure to decrypt items
|
||||
}
|
||||
}, [items]);
|
||||
|
||||
|
|
|
@ -20,6 +20,7 @@ import { getCollectionManager } from "../etebase-helpers";
|
|||
import { CachedCollection } from "../Pim/helpers";
|
||||
|
||||
import CollectionMemberAddDialog from "./CollectionMemberAddDialog";
|
||||
import Alert from "@material-ui/lab/Alert";
|
||||
|
||||
interface PropsType {
|
||||
collection: CachedCollection;
|
||||
|
@ -30,15 +31,19 @@ export default function CollectionMembers(props: PropsType) {
|
|||
const [members_, setMembers] = React.useState<Etebase.CollectionMember[]>();
|
||||
const [revokeUser, setRevokeUser] = React.useState<string | null>(null);
|
||||
const [addMemberOpen, setAddMemberOpen] = React.useState(false);
|
||||
// FIXME: add error handling
|
||||
const [error, setError] = React.useState<Error>();
|
||||
|
||||
const { collection, metadata } = props.collection;
|
||||
|
||||
async function fetchMembers() {
|
||||
const colMgr = getCollectionManager(etebase);
|
||||
const memberManager = colMgr.getMemberManager(collection);
|
||||
const members = await memberManager.list();
|
||||
setMembers(members.data);
|
||||
try {
|
||||
const members = await memberManager.list();
|
||||
setMembers(members.data);
|
||||
} catch (e) {
|
||||
setError(e);
|
||||
}
|
||||
}
|
||||
|
||||
React.useEffect(() => {
|
||||
|
@ -70,6 +75,11 @@ export default function CollectionMembers(props: PropsType) {
|
|||
<>
|
||||
<AppBarOverride title={`${metadata.name} - Members`} />
|
||||
<Container style={{ maxWidth: "30rem" }}>
|
||||
{error && (
|
||||
<Alert color="error">
|
||||
{error.toString()}
|
||||
</Alert>
|
||||
)}
|
||||
{members ?
|
||||
<List>
|
||||
<ListItem rightIcon={<IconMemberAdd />} onClick={() => setAddMemberOpen(true)}>
|
||||
|
|
|
@ -37,16 +37,16 @@ export default function ContactsMain() {
|
|||
const items = useItems(etebase, colType);
|
||||
|
||||
React.useEffect(() => {
|
||||
if (items) {
|
||||
decryptItems(items)
|
||||
.then((entries) => setEntries(entries));
|
||||
// FIXME: handle failure to decrypt items
|
||||
}
|
||||
if (collections) {
|
||||
decryptCollections(collections)
|
||||
.then((entries) => setCachedCollections(entries));
|
||||
// FIXME: handle failure to decrypt collections
|
||||
if (!collections || !items) {
|
||||
return;
|
||||
}
|
||||
(async () => {
|
||||
const colEntries = await decryptCollections(collections);
|
||||
const entries = await decryptItems(items);
|
||||
|
||||
setCachedCollections(colEntries);
|
||||
setEntries(entries);
|
||||
})();
|
||||
}, [items, collections]);
|
||||
|
||||
if (!entries || !cachedCollections) {
|
||||
|
|
|
@ -11,8 +11,8 @@ import * as Etebase from "etebase";
|
|||
|
||||
import { PimType } from "../pim-types";
|
||||
import { getCollectionManager } from "../etebase-helpers";
|
||||
import { asyncDispatch } from "../store";
|
||||
import { itemBatch } from "../store/actions";
|
||||
import { asyncDispatch, store } from "../store";
|
||||
import { itemBatch, appendError } from "../store/actions";
|
||||
|
||||
export const defaultColor = "#8BC34A";
|
||||
|
||||
|
@ -32,10 +32,14 @@ export function getDecryptCollectionsFunction(_colType?: string) {
|
|||
const entries: CachedCollection[] = [];
|
||||
if (collections) {
|
||||
for (const collection of collections) {
|
||||
entries.push({
|
||||
collection,
|
||||
metadata: await collection.getMeta(),
|
||||
});
|
||||
try {
|
||||
entries.push({
|
||||
collection,
|
||||
metadata: await collection.getMeta(),
|
||||
});
|
||||
} catch (e) {
|
||||
store.dispatch(appendError(e));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -54,10 +58,14 @@ export function getDecryptItemsFunction<T extends PimType>(_colType: string, par
|
|||
const cur = new Map();
|
||||
entries.set(colUid, cur);
|
||||
for (const item of col.values()) {
|
||||
const contact = parseFunc(await item.getContent(Etebase.OutputFormat.String));
|
||||
contact.collectionUid = colUid;
|
||||
contact.itemUid = item.uid;
|
||||
cur.set(item.uid, contact);
|
||||
try {
|
||||
const contact = parseFunc(await item.getContent(Etebase.OutputFormat.String));
|
||||
contact.collectionUid = colUid;
|
||||
contact.itemUid = item.uid;
|
||||
cur.set(item.uid, contact);
|
||||
} catch (e) {
|
||||
store.dispatch(appendError(e));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -37,16 +37,16 @@ export default function TasksMain() {
|
|||
const items = useItems(etebase, colType);
|
||||
|
||||
React.useEffect(() => {
|
||||
if (items) {
|
||||
decryptItems(items)
|
||||
.then((entries) => setEntries(entries));
|
||||
// FIXME: handle failure to decrypt items
|
||||
}
|
||||
if (collections) {
|
||||
decryptCollections(collections)
|
||||
.then((entries) => setCachedCollections(entries));
|
||||
// FIXME: handle failure to decrypt collections
|
||||
if (!collections || !items) {
|
||||
return;
|
||||
}
|
||||
(async () => {
|
||||
const colEntries = await decryptCollections(collections);
|
||||
const entries = await decryptItems(items);
|
||||
|
||||
setCachedCollections(colEntries);
|
||||
setEntries(entries);
|
||||
})();
|
||||
}, [items, collections]);
|
||||
|
||||
if (!entries || !cachedCollections) {
|
||||
|
|
|
@ -168,7 +168,7 @@ export const performSync = createAction(
|
|||
|
||||
export const appendError = createAction(
|
||||
"APPEND_ERROR",
|
||||
(_etesync: Etebase.Account, error: Error | Error[]) => {
|
||||
(error: Error | Error[]) => {
|
||||
return Array.isArray(error) ? error : [error];
|
||||
}
|
||||
);
|
||||
|
|
|
@ -6,7 +6,7 @@ import * as Etebase from "etebase";
|
|||
import { store, StoreState } from "../store";
|
||||
|
||||
import { credentialsSelector } from "../credentials";
|
||||
import { setSyncCollection, setSyncGeneral, setCacheCollection, unsetCacheCollection, setCacheItemMulti } from "../store/actions";
|
||||
import { setSyncCollection, setSyncGeneral, setCacheCollection, unsetCacheCollection, setCacheItemMulti, appendError } from "../store/actions";
|
||||
|
||||
const cachedSyncManager = new Map<string, SyncManager>();
|
||||
export class SyncManager {
|
||||
|
@ -105,7 +105,7 @@ export class SyncManager {
|
|||
case 401: // INVALID TOKEN
|
||||
case 403: // FORBIDDEN
|
||||
case 503: // UNAVAILABLE
|
||||
// FIXME store.dispatch(addNonFatalError(this.etebase, e));
|
||||
store.dispatch(appendError(e));
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue