Merge pull request #905 from ente-io/update-filetype-error-handling

Update filetype error handling
This commit is contained in:
Abhinav Kumar 2023-02-02 18:31:43 +05:30 committed by GitHub
commit 286dd45166
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 77 additions and 71 deletions

View file

@ -533,7 +533,7 @@ export default function Uploader(props: Props) {
}
};
function showUserFacingError(err: CustomError) {
function showUserFacingError(err: string) {
let notification: NotificationAttributes;
switch (err) {
case CustomError.SESSION_EXPIRED:

View file

@ -15,6 +15,8 @@ export const FILE_TYPE_LIB_MISSED_FORMATS = [
{ fileType: FILE_TYPE.VIDEO, exactType: 'mp4', mimeType: 'video/mp4' },
];
export const KNOWN_NON_MEDIA_FORMATS = ['xmp'];
export const EXIFLESS_FORMATS = ['image/gif'];
export const EXIF_LIBRARY_UNSUPPORTED_FORMATS = ['image/webp'];

View file

@ -1,6 +1,9 @@
import { FILE_TYPE } from 'constants/file';
import { ElectronFile, FileTypeInfo } from 'types/upload';
import { FILE_TYPE_LIB_MISSED_FORMATS } from 'constants/upload';
import {
FILE_TYPE_LIB_MISSED_FORMATS,
KNOWN_NON_MEDIA_FORMATS,
} from 'constants/upload';
import { CustomError } from 'utils/error';
import { getFileExtension } from 'utils/file';
import { logError } from 'utils/sentry';
@ -27,7 +30,7 @@ export async function getFileType(
const mimTypeParts: string[] = typeResult.mime?.split('/');
if (mimTypeParts?.length !== 2) {
throw Error(CustomError.TYPE_DETECTION_FAILED);
throw Error(CustomError.INVALID_MIME_TYPE(typeResult.mime));
}
switch (mimTypeParts[0]) {
case TYPE_IMAGE:
@ -37,7 +40,7 @@ export async function getFileType(
fileType = FILE_TYPE.VIDEO;
break;
default:
fileType = FILE_TYPE.OTHERS;
throw Error(CustomError.UNSUPPORTED_FILE_FORMAT);
}
return {
fileType,
@ -45,6 +48,9 @@ export async function getFileType(
mimeType: typeResult.mime,
};
} catch (e) {
if (e.message === CustomError.UNSUPPORTED_FILE_FORMAT) {
throw e;
}
const fileFormat = getFileExtension(receivedFile.name);
const formatMissedByTypeDetection = FILE_TYPE_LIB_MISSED_FORMATS.find(
(a) => a.exactType === fileFormat
@ -52,14 +58,13 @@ export async function getFileType(
if (formatMissedByTypeDetection) {
return formatMissedByTypeDetection;
}
logError(e, CustomError.TYPE_DETECTION_FAILED, {
if (KNOWN_NON_MEDIA_FORMATS.includes(fileFormat)) {
throw Error(CustomError.UNSUPPORTED_FILE_FORMAT);
}
logError(e, 'type detection failed', {
fileFormat,
});
return {
fileType: FILE_TYPE.OTHERS,
exactType: fileFormat,
mimeType: receivedFile instanceof File ? receivedFile.type : null,
};
throw Error(CustomError.TYPE_DETECTION_FAILED(fileFormat));
}
}
@ -78,18 +83,15 @@ async function extractElectronFileType(file: ElectronFile) {
}
async function getFileTypeFromBuffer(buffer: Uint8Array) {
try {
const result = await FileType.fromBuffer(buffer);
if (!result.mime) {
logError(
Error('mimetype missing from file type result'),
CustomError.TYPE_DETECTION_FAILED,
{ result }
);
throw Error(CustomError.TYPE_DETECTION_FAILED);
const result = await FileType.fromBuffer(buffer);
if (!result?.mime) {
let logableInfo = '';
try {
logableInfo = `result: ${JSON.stringify(result)}`;
} catch (e) {
logableInfo = 'failed to stringify result';
}
return result;
} catch (e) {
throw Error(CustomError.TYPE_DETECTION_FAILED);
throw Error(`mimetype missing from file type result - ${logableInfo}`);
}
return result;
}

View file

@ -51,10 +51,9 @@ export default async function uploader(
}
addLogLine(`getting filetype for ${fileNameSize}`);
fileTypeInfo = await UploadService.getAssetFileType(uploadAsset);
addLogLine(`got filetype for ${fileNameSize}`);
if (fileTypeInfo.fileType === FILE_TYPE.OTHERS) {
throw Error(CustomError.UNSUPPORTED_FILE_FORMAT);
}
addLogLine(
`got filetype for ${fileNameSize} - ${JSON.stringify(fileTypeInfo)}`
);
if (skipVideos && fileTypeInfo.fileType === FILE_TYPE.VIDEO) {
addLogLine(
`skipped video upload for public upload ${fileNameSize}`
@ -176,7 +175,10 @@ export default async function uploader(
};
} catch (e) {
addLogLine(`upload failed for ${fileNameSize} ,error: ${e.message}`);
if (e.message !== CustomError.UPLOAD_CANCELLED) {
if (
e.message !== CustomError.UPLOAD_CANCELLED &&
e.message !== CustomError.UNSUPPORTED_FILE_FORMAT
) {
logError(e, 'file upload failed', {
fileFormat: fileTypeInfo?.exactType,
});

View file

@ -11,45 +11,49 @@ export const ServerErrorCodes = {
NOT_FOUND: '404',
};
export enum CustomError {
SUBSCRIPTION_VERIFICATION_ERROR = 'Subscription verification failed',
THUMBNAIL_GENERATION_FAILED = 'thumbnail generation failed',
VIDEO_PLAYBACK_FAILED = 'video playback failed',
ETAG_MISSING = 'no header/etag present in response body',
KEY_MISSING = 'encrypted key missing from localStorage',
FAILED_TO_LOAD_WEB_WORKER = 'failed to load web worker',
CHUNK_MORE_THAN_EXPECTED = 'chunks more than expected',
CHUNK_LESS_THAN_EXPECTED = 'chunks less than expected',
UNSUPPORTED_FILE_FORMAT = 'unsupported file formats',
FILE_TOO_LARGE = 'file too large',
SUBSCRIPTION_EXPIRED = 'subscription expired',
STORAGE_QUOTA_EXCEEDED = 'storage quota exceeded',
SESSION_EXPIRED = 'session expired',
TYPE_DETECTION_FAILED = 'type detection failed',
SIGNUP_FAILED = 'signup failed',
FAV_COLLECTION_MISSING = 'favorite collection missing',
INVALID_COLLECTION_OPERATION = 'invalid collection operation',
WAIT_TIME_EXCEEDED = 'thumbnail generation wait time exceeded',
REQUEST_CANCELLED = 'request canceled',
REQUEST_FAILED = 'request failed',
TOKEN_EXPIRED = 'token expired',
TOKEN_MISSING = 'token missing',
TOO_MANY_REQUESTS = 'too many requests',
BAD_REQUEST = 'bad request',
SUBSCRIPTION_NEEDED = 'subscription not present',
NOT_FOUND = 'not found ',
NO_METADATA = 'no metadata',
TOO_LARGE_LIVE_PHOTO_ASSETS = 'too large live photo assets',
NOT_A_DATE = 'not a date',
FILE_ID_NOT_FOUND = 'file with id not found',
WEAK_DEVICE = 'password decryption failed on the device',
INCORRECT_PASSWORD = 'incorrect password',
UPLOAD_CANCELLED = 'upload cancelled',
REQUEST_TIMEOUT = 'request taking too long',
HIDDEN_COLLECTION_SYNC_FILE_ATTEMPTED = 'hidden collection sync file attempted',
UNKNOWN_ERROR = 'Something went wrong, please try again',
WINDOWS_NATIVE_IMAGE_PROCESSING_NOT_SUPPORTED = 'Windows native image processing is not supported',
}
export const CustomError = {
SUBSCRIPTION_VERIFICATION_ERROR: 'Subscription verification failed',
THUMBNAIL_GENERATION_FAILED: 'thumbnail generation failed',
VIDEO_PLAYBACK_FAILED: 'video playback failed',
ETAG_MISSING: 'no header/etag present in response body',
KEY_MISSING: 'encrypted key missing from localStorage',
FAILED_TO_LOAD_WEB_WORKER: 'failed to load web worker',
CHUNK_MORE_THAN_EXPECTED: 'chunks more than expected',
CHUNK_LESS_THAN_EXPECTED: 'chunks less than expected',
UNSUPPORTED_FILE_FORMAT: 'unsupported file format',
FILE_TOO_LARGE: 'file too large',
SUBSCRIPTION_EXPIRED: 'subscription expired',
STORAGE_QUOTA_EXCEEDED: 'storage quota exceeded',
SESSION_EXPIRED: 'session expired',
INVALID_MIME_TYPE: (type: string) => `invalid mime type -${type}`,
SIGNUP_FAILED: 'signup failed',
FAV_COLLECTION_MISSING: 'favorite collection missing',
INVALID_COLLECTION_OPERATION: 'invalid collection operation',
WAIT_TIME_EXCEEDED: 'thumbnail generation wait time exceeded',
REQUEST_CANCELLED: 'request canceled',
REQUEST_FAILED: 'request failed',
TOKEN_EXPIRED: 'token expired',
TOKEN_MISSING: 'token missing',
TOO_MANY_REQUESTS: 'too many requests',
BAD_REQUEST: 'bad request',
SUBSCRIPTION_NEEDED: 'subscription not present',
NOT_FOUND: 'not found ',
NO_METADATA: 'no metadata',
TOO_LARGE_LIVE_PHOTO_ASSETS: 'too large live photo assets',
NOT_A_DATE: 'not a date',
FILE_ID_NOT_FOUND: 'file with id not found',
WEAK_DEVICE: 'password decryption failed on the device',
INCORRECT_PASSWORD: 'incorrect password',
UPLOAD_CANCELLED: 'upload cancelled',
REQUEST_TIMEOUT: 'request taking too long',
HIDDEN_COLLECTION_SYNC_FILE_ATTEMPTED:
'hidden collection sync file attempted',
UNKNOWN_ERROR: 'Something went wrong, please try again',
TYPE_DETECTION_FAILED: (fileFormat: string) =>
`type detection failed ${fileFormat}`,
WINDOWS_NATIVE_IMAGE_PROCESSING_NOT_SUPPORTED:
'Windows native image processing is not supported',
};
function parseUploadErrorCodes(error) {
let parsedMessage = null;

View file

@ -1,5 +1,4 @@
import * as Sentry from '@sentry/nextjs';
import { isDEVSentryENV } from 'constants/sentry';
import { addLogLine } from 'utils/logging';
import { getSentryUserID } from 'utils/user';
@ -17,12 +16,9 @@ export const logError = async (
addLogLine(
`error: ${error?.name} ${error?.message} ${
error?.stack
} msg: ${msg} info: ${JSON.stringify(info)}`
} msg: ${msg} ${info ? `info: ${JSON.stringify(info)}` : ''}`
);
}
if (isDEVSentryENV()) {
console.log(error, { msg, info });
}
Sentry.captureException(err, {
level: Sentry.Severity.Info,
user: { id: await getSentryUserID() },