show notification on upload errors

This commit is contained in:
Abhinav 2022-06-07 20:07:14 +05:30
parent f7a6c3e0d0
commit a70f7c9254
4 changed files with 59 additions and 52 deletions

View file

@ -16,15 +16,17 @@ import uploadManager from 'services/upload/uploadManager';
import ImportService from 'services/importService';
import isElectron from 'is-electron';
import { METADATA_FOLDER_NAME } from 'constants/export';
import { getUserFacingErrorMessage } from 'utils/error';
import { CustomError } from 'utils/error';
import { Collection } from 'types/collection';
import { SetLoading, SetFiles } from 'types/gallery';
import { SetLoading, SetFiles, NotificationAttributes } from 'types/gallery';
import { FileUploadResults, UPLOAD_STAGES } from 'constants/upload';
import { ElectronFile, FileWithCollection } from 'types/upload';
import UploadTypeSelector from '../../UploadTypeSelector';
import Router from 'next/router';
import { isCanvasBlocked } from 'utils/upload/isCanvasBlocked';
import { downloadApp } from 'utils/common';
import DiscFullIcon from '@mui/icons-material/DiscFull';
import { logoutUser } from 'services/userService';
const FIRST_ALBUM_NAME = 'My First Album';
@ -350,11 +352,9 @@ export default function Upload(props: Props) {
collections
);
} catch (err) {
const message = getUserFacingErrorMessage(
err.message,
galleryContext.showPlanSelectorModal
galleryContext.setNotificationAttributes(
getErrorNotification(err.message)
);
props.setBannerMessage(message);
setProgressView(false);
throw err;
} finally {
@ -362,6 +362,7 @@ export default function Upload(props: Props) {
props.syncWithRemote();
}
};
const retryFailed = async () => {
try {
props.setUploadInProgress(true);
@ -369,12 +370,9 @@ export default function Upload(props: Props) {
await props.syncWithRemote(true, true);
await uploadManager.retryFailedFiles();
} catch (err) {
const message = getUserFacingErrorMessage(
err.message,
galleryContext.showPlanSelectorModal
galleryContext.setNotificationAttributes(
getErrorNotification(err.message)
);
appContext.resetSharedFiles();
props.setBannerMessage(message);
setProgressView(false);
} finally {
props.setUploadInProgress(false);
@ -382,6 +380,45 @@ export default function Upload(props: Props) {
}
};
function getErrorNotification(err: CustomError): NotificationAttributes {
switch (err) {
case CustomError.SESSION_EXPIRED:
return {
variant: 'danger',
message: constants.SESSION_EXPIRED,
action: {
text: constants.LOGIN,
callback: logoutUser,
},
};
case CustomError.SUBSCRIPTION_EXPIRED:
return {
variant: 'danger',
message: constants.SUBSCRIPTION_EXPIRED,
action: {
text: constants.UPGRADE_NOW,
callback: galleryContext.showPlanSelectorModal,
},
};
case CustomError.STORAGE_QUOTA_EXCEEDED:
return {
variant: 'danger',
message: constants.STORAGE_QUOTA_EXCEEDED,
action: {
text: constants.RENEW_NOW,
callback: galleryContext.showPlanSelectorModal,
},
icon: <DiscFullIcon fontSize="large" />,
};
default:
return {
variant: 'danger',
message: constants.UNKNOWN_ERROR,
};
}
}
const uploadToSingleNewCollection = (collectionName: string) => {
if (collectionName) {
uploadFilesToNewCollections(

View file

@ -1,4 +1,5 @@
import { ButtonProps } from '@mui/material';
import { ReactNode } from 'react';
import { Collection } from 'types/collection';
import { EnteFile } from 'types/file';
import { Search, SearchResultSummary } from 'types/search';
@ -29,6 +30,7 @@ export type GalleryContextType = {
};
export interface NotificationAttributes {
icon?: ReactNode;
variant: ButtonProps['color'];
message: JSX.Element | string;
action?: {

View file

@ -26,7 +26,7 @@ export enum CustomError {
FILE_TOO_LARGE = 'file too large',
SUBSCRIPTION_EXPIRED = 'subscription expired',
STORAGE_QUOTA_EXCEEDED = 'storage quota exceeded',
SESSION_EXPIRED_MESSAGE = 'session expired',
SESSION_EXPIRED = 'session expired',
TYPE_DETECTION_FAILED = 'type detection failed',
SIGNUP_FAILED = 'signup failed',
FAV_COLLECTION_MISSING = 'favorite collection missing',
@ -57,7 +57,7 @@ function parseUploadErrorCodes(error) {
parsedMessage = CustomError.STORAGE_QUOTA_EXCEEDED;
break;
case ServerErrorCodes.SESSION_EXPIRED:
parsedMessage = CustomError.SESSION_EXPIRED_MESSAGE;
parsedMessage = CustomError.SESSION_EXPIRED;
break;
case ServerErrorCodes.FILE_TOO_LARGE:
parsedMessage = CustomError.FILE_TOO_LARGE;
@ -78,28 +78,12 @@ export function handleUploadError(error): Error {
switch (parsedError.message) {
case CustomError.SUBSCRIPTION_EXPIRED:
case CustomError.STORAGE_QUOTA_EXCEEDED:
case CustomError.SESSION_EXPIRED_MESSAGE:
case CustomError.SESSION_EXPIRED:
throw parsedError;
}
return parsedError;
}
export function getUserFacingErrorMessage(
err: CustomError,
action: () => void
) {
switch (err) {
case CustomError.SESSION_EXPIRED_MESSAGE:
return constants.SESSION_EXPIRED_MESSAGE;
case CustomError.SUBSCRIPTION_EXPIRED:
return constants.SUBSCRIPTION_EXPIRED(action);
case CustomError.STORAGE_QUOTA_EXCEEDED:
return constants.STORAGE_QUOTA_EXCEEDED(action);
default:
return constants.UNKNOWN_ERROR;
}
}
export function errorWithContext(originalError: Error, context: string) {
const errorWithContext = new Error(context);
errorWithContext.stack =

View file

@ -27,14 +27,6 @@ const Logo = styled.img`
margin-top: -3px;
`;
const Trigger = styled.span`
:hover {
text-decoration: underline;
cursor: pointer;
}
color: #51cd7c;
`;
const englishConstants = {
ENTE: 'ente',
HERO_HEADER: () => (
@ -79,7 +71,7 @@ const englishConstants = {
ENTER_OTT: 'verification code',
RESEND_MAIL: 'Resend code',
VERIFY: 'verify',
UNKNOWN_ERROR: 'something went wrong, please try again',
UNKNOWN_ERROR: 'Something went wrong, please try again',
INVALID_CODE: 'invalid verification code',
EXPIRED_CODE: 'your verification code has expired',
SENDING: 'sending...',
@ -132,18 +124,8 @@ const englishConstants = {
},
UPLOADING_FILES: 'file upload',
FILE_NOT_UPLOADED_LIST: 'the following files were not uploaded',
SUBSCRIPTION_EXPIRED: (action) => (
<>
your subscription has expired, please a{' '}
<Trigger onClick={action}>renew</Trigger>
</>
),
STORAGE_QUOTA_EXCEEDED: (action) => (
<>
you have exceeded your storage quota, please{' '}
<Trigger onClick={action}>upgrade</Trigger> your plan
</>
),
SUBSCRIPTION_EXPIRED: 'Subscription expired',
STORAGE_QUOTA_EXCEEDED: 'Storage limit exceeded',
INITIAL_LOAD_DELAY_WARNING: 'the first load may take some time',
USER_DOES_NOT_EXIST: 'sorry, could not find a user with that email',
UPLOAD_BUTTON_TEXT: 'upload',
@ -173,7 +155,7 @@ const englishConstants = {
UPLOAD_STRATEGY_COLLECTION_PER_FOLDER: 'separate albums',
SESSION_EXPIRED_MESSAGE:
'your session has expired, please login again to continue',
SESSION_EXPIRED: 'session expired',
SESSION_EXPIRED: 'Session expired',
SYNC_FAILED: 'failed to sync with server, please refresh this page',
PASSWORD_GENERATION_FAILED:
"your browser was unable to generate a strong key that meets ente's encryption standards, please try using the mobile app or another browser",
@ -789,6 +771,8 @@ const englishConstants = {
</p>
</>
),
UPGRADE_NOW: 'Upgrade now',
RENEW_NOW: 'Renew now',
};
export default englishConstants;