handle sharing errors

This commit is contained in:
Abhinav 2022-01-21 18:24:57 +05:30
parent 13f8968ee9
commit a358525b36
5 changed files with 77 additions and 33 deletions

View file

@ -1,4 +1,4 @@
import React, { useContext, useState } from 'react'; import React, { useContext, useEffect, useState } from 'react';
import constants from 'utils/strings/constants'; import constants from 'utils/strings/constants';
import { Formik, FormikHelpers } from 'formik'; import { Formik, FormikHelpers } from 'formik';
import * as Yup from 'yup'; import * as Yup from 'yup';
@ -20,6 +20,8 @@ import { Collection } from 'types/collection';
import { transformShareURLForHost } from 'utils/collection'; import { transformShareURLForHost } from 'utils/collection';
import { Row, Value } from './Container'; import { Row, Value } from './Container';
import { CodeBlock } from './CodeBlock'; import { CodeBlock } from './CodeBlock';
import { ButtonVariant, getVariantColor } from './pages/gallery/LinkButton';
import { handleSharingErrors } from 'utils/error';
interface Props { interface Props {
show: boolean; show: boolean;
@ -38,6 +40,13 @@ interface ShareeProps {
function CollectionShare(props: Props) { function CollectionShare(props: Props) {
const [loading, setLoading] = useState(false); const [loading, setLoading] = useState(false);
const galleryContext = useContext(GalleryContext); const galleryContext = useContext(GalleryContext);
const [sharableLinkError, setSharableLinkError] = useState(null);
const [publicShareUrl, setPublicShareUrl] = useState<string>(null);
useEffect(
() => setPublicShareUrl(props.collection?.publicURLs?.[0]?.url || null),
[props.collection]
);
const collectionShare = async ( const collectionShare = async (
{ email }: formValues, { email }: formValues,
@ -58,20 +67,7 @@ function CollectionShare(props: Props) {
resetForm(); resetForm();
} }
} catch (e) { } catch (e) {
let errorMessage = null; const errorMessage = handleSharingErrors(e);
switch (e?.status) {
case 400:
errorMessage = constants.SHARING_BAD_REQUEST_ERROR;
break;
case 402:
errorMessage = constants.SHARING_DISABLED_FOR_FREE_ACCOUNTS;
break;
case 404:
errorMessage = constants.USER_DOES_NOT_EXIST;
break;
default:
errorMessage = `${constants.UNKNOWN_ERROR} ${e.message}`;
}
setFieldError('email', errorMessage); setFieldError('email', errorMessage);
} finally { } finally {
setLoading(false); setLoading(false);
@ -83,14 +79,31 @@ function CollectionShare(props: Props) {
}; };
const createSharableURLHelper = async () => { const createSharableURLHelper = async () => {
const publicURL = await createShareableURL(props.collection); try {
props.collection.publicURLs = [publicURL]; galleryContext.startLoading();
await props.syncWithRemote(); const publicURL = await createShareableURL(props.collection);
galleryContext.finishLoading();
setPublicShareUrl(publicURL.url);
await galleryContext.syncWithRemote(false, true);
} catch (e) {
const errorMessage = handleSharingErrors(e);
setSharableLinkError(errorMessage);
} finally {
galleryContext.finishLoading();
}
}; };
const deleteSharableURLHelper = async () => { const deleteSharableURLHelper = async () => {
await deleteShareableURL(props.collection); try {
await props.syncWithRemote(); await deleteShareableURL(props.collection);
setPublicShareUrl(null);
await galleryContext.syncWithRemote(false, true);
} catch (e) {
const errorMessage = handleSharingErrors(e);
setSharableLinkError(errorMessage);
} finally {
galleryContext.finishLoading();
}
}; };
const deleteSharableLink = () => { const deleteSharableLink = () => {
@ -107,7 +120,8 @@ function CollectionShare(props: Props) {
}; };
const handleCollectionPublicSharing = () => { const handleCollectionPublicSharing = () => {
if (props.collection.publicURLs?.length > 0) { setSharableLinkError(null);
if (publicShareUrl) {
deleteSharableLink(); deleteSharableLink();
} else { } else {
createSharableURLHelper(); createSharableURLHelper();
@ -206,12 +220,19 @@ function CollectionShare(props: Props) {
</Value> </Value>
<Form.Switch <Form.Switch
style={{ marginLeft: '20px' }} style={{ marginLeft: '20px' }}
checked={props.collection.publicURLs?.length > 0} checked={!!publicShareUrl}
id="collection-public-sharing-toggler" id="collection-public-sharing-toggler"
className="custom-switch-md" className="custom-switch-md"
onChange={handleCollectionPublicSharing} onChange={handleCollectionPublicSharing}
/> />
</Row> </Row>
<Row
style={{
margin: '10px',
color: getVariantColor(ButtonVariant.danger),
}}>
{sharableLinkError}
</Row>
<div <div
style={{ style={{
height: '1px', height: '1px',
@ -221,7 +242,7 @@ function CollectionShare(props: Props) {
}} }}
/> />
{props.collection.publicURLs?.length > 0 && ( {publicShareUrl && (
<div style={{ width: '100%', wordBreak: 'break-all' }}> <div style={{ width: '100%', wordBreak: 'break-all' }}>
<>{constants.PUBLIC_URL}</> <>{constants.PUBLIC_URL}</>
<CodeBlock <CodeBlock

View file

@ -123,6 +123,8 @@ const defaultGalleryContext: GalleryContextType = {
setActiveCollection: () => null, setActiveCollection: () => null,
syncWithRemote: () => null, syncWithRemote: () => null,
setDialogMessage: () => null, setDialogMessage: () => null,
startLoading: () => null,
finishLoading: () => null,
}; };
export const GalleryContext = createContext<GalleryContextType>( export const GalleryContext = createContext<GalleryContextType>(
@ -546,6 +548,8 @@ export default function Gallery() {
setActiveCollection, setActiveCollection,
syncWithRemote, syncWithRemote,
setDialogMessage, setDialogMessage,
startLoading,
finishLoading,
}}> }}>
<FullScreenDropZone <FullScreenDropZone
getRootProps={getRootProps} getRootProps={getRootProps}

View file

@ -577,7 +577,6 @@ export const unshareCollection = async (
); );
} catch (e) { } catch (e) {
logError(e, 'unshare collection failed '); logError(e, 'unshare collection failed ');
throw e;
} }
}; };

View file

@ -31,4 +31,6 @@ export type GalleryContextType = {
setActiveCollection: (collection: number) => void; setActiveCollection: (collection: number) => void;
syncWithRemote: (force?: boolean, silent?: boolean) => Promise<void>; syncWithRemote: (force?: boolean, silent?: boolean) => Promise<void>;
setDialogMessage: SetDialogMessage; setDialogMessage: SetDialogMessage;
startLoading: () => void;
finishLoading: () => void;
}; };

View file

@ -51,17 +51,13 @@ function parseUploadError(error: AxiosResponse) {
case ServerErrorCodes.FILE_TOO_LARGE: case ServerErrorCodes.FILE_TOO_LARGE:
parsedMessage = CustomError.FILE_TOO_LARGE; parsedMessage = CustomError.FILE_TOO_LARGE;
break; break;
default:
parsedMessage = `${constants.UNKNOWN_ERROR} statusCode:${errorCode}`;
} }
} }
if (parsedMessage) { return {
return { parsedError: new Error(parsedMessage),
parsedError: new Error(parsedMessage), };
};
} else {
return {
parsedError: new Error(CustomError.UNKNOWN_ERROR),
};
}
} }
export function handleUploadError(error: AxiosResponse | Error): Error { export function handleUploadError(error: AxiosResponse | Error): Error {
@ -105,3 +101,25 @@ export function errorWithContext(originalError: Error, context: string) {
originalError.stack; originalError.stack;
return errorWithContext; return errorWithContext;
} }
export const handleSharingErrors = (e) => {
let errorMessage = null;
if ('status' in e) {
switch (e?.status) {
case 400:
errorMessage = constants.SHARING_BAD_REQUEST_ERROR;
break;
case 402:
errorMessage = constants.SHARING_DISABLED_FOR_FREE_ACCOUNTS;
break;
case 404:
errorMessage = constants.USER_DOES_NOT_EXIST;
break;
default:
errorMessage = `${constants.UNKNOWN_ERROR} statusCode:${e.status}`;
}
} else {
errorMessage = e.message;
}
return errorMessage;
};