show notification on upload errors
This commit is contained in:
parent
f7a6c3e0d0
commit
a70f7c9254
|
@ -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(
|
||||
|
|
|
@ -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?: {
|
||||
|
|
|
@ -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 =
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue