improve error handling

closes #2797
pull/2801/head
Mikael Finstad 4 months ago
parent 2603134dcc
commit 260313b7c9
No known key found for this signature in database
GPG Key ID: 25AB36E3E81CBC26

@ -711,6 +711,7 @@
"Some extra tracks have been discarded. You can change this option before merging.": "Some extra tracks have been discarded. You can change this option before merging.",
"Something went wrong": "Something went wrong",
"Sort items": "Sort items",
"Source file no longer exists or is not accessible. Please check that it is still in its original location and that you have permission to access it.": "Source file no longer exists or is not accessible. Please check that it is still in its original location and that you have permission to access it.",
"Source file's time minus segment end cut time": "Source file's time minus segment end cut time",
"Source file's time plus segment start cut time": "Source file's time plus segment start cut time",
"Speed up playback": "Speed up playback",

@ -78,6 +78,7 @@ import {
shootConfetti,
isMasBuild,
readFileStats,
makeSourceFileAccessError,
} from './util';
import getSwal, { errorToast, showPlaybackFailedMessage } from './swal';
import { adjustRate } from './util/rate-calculator';
@ -918,7 +919,13 @@ function App() {
chaptersFromSegments = await createChaptersFromSegments({ segmentPaths: paths, chapterNames });
}
const inputSize = sum(await readFileSizes(paths));
let inputSize: number;
try {
inputSize = sum(await readFileSizes(paths));
} catch (err) {
console.warn('Unable to read input file sizes', err);
throw makeSourceFileAccessError();
}
// console.log('merge', paths);
const metadataFromPath = paths[0];
@ -964,6 +971,11 @@ function App() {
return;
}
if (err instanceof UserFacingError) {
errorToast(err.message);
return;
}
const reportState = { includeAllStreams, streams, outFormat, clearBatchFilesAfterConcat };
handleConcatFailed(err, reportState);
} finally {
@ -1212,6 +1224,11 @@ function App() {
return;
}
if (err instanceof UserFacingError) {
errorToast(err.message);
return;
}
handleExportFailed(err);
} finally {
setWorking(undefined);

@ -5,7 +5,7 @@ import pMap from 'p-map';
import invariant from 'tiny-invariant';
import i18n from 'i18next';
import { getSuffixedOutPath, transferTimestamps, getOutFileExtension, getOutDir, deleteDispositionValue, getHtml5ifiedPath, unlinkWithRetry, getFrameDuration, isMac, html5ifiedPrefix, html5dummySuffix } from '../util';
import { getSuffixedOutPath, transferTimestamps, getOutFileExtension, getOutDir, deleteDispositionValue, getHtml5ifiedPath, unlinkWithRetry, getFrameDuration, isMac, html5ifiedPrefix, html5dummySuffix, assertFileExists } from '../util';
import { isCuttingStart, isCuttingEnd, runFfmpegWithProgress, getFfCommandLine, getDuration, createChaptersFromSegments, readFileFfprobeMeta, getExperimentalArgs, getVideoTimescaleArgs, logStdoutStderr, runFfmpegConcat, RefuseOverwriteError, runFfmpeg } from '../ffmpeg';
import { getMapStreamsArgs, getStreamIdsToCopy } from '../util/streams';
import { needsSmartCut, getCodecParams } from '../smartcut';
@ -531,13 +531,16 @@ function useFfmpegOperations({ filePath, treatInputFileModifiedTimeAsStart, trea
return onTotalProgress((sum(Object.values(singleProgresses)) / segments.length));
}
invariant(filePath != null);
await assertFileExists(filePath);
const chaptersPath = await writeChaptersFfmetadata(outputDir, chapters);
// This function will either call losslessCutSingle (if no smart cut enabled)
// or if enabled, will first cut&encode the part before the next keyframe, trying to match the input file's codec params
// then it will cut the part *from* the keyframe to "end", and concat them together and return the concated file
// so that for the calling code it looks as if it's just a normal segment
async function cutSegment({ start: desiredCutFrom, end: cutTo }: { start: number, end: number }, i: number) {
const cutSegment = async ({ start: desiredCutFrom, end: cutTo }: { start: number, end: number }, i: number) => {
const onProgress = (progress: number) => onSingleProgress(i, progress / 2);
const onConcatProgress = (progress: number) => onSingleProgress(i, (1 + progress) / 2);
@ -556,8 +559,7 @@ function useFfmpegOperations({ filePath, treatInputFileModifiedTimeAsStart, trea
return { path: finalOutPath, created: true };
}
// we are probably encoding (smart cut or lossy mode)
invariant(filePath != null);
// we are probably encoding (`isEncoding`: true, smart cut or lossy mode)
// smart cut only supports cutting main file (no externally added files)
const { streams } = allFilesMeta[filePath]!;
@ -651,7 +653,7 @@ function useFfmpegOperations({ filePath, treatInputFileModifiedTimeAsStart, trea
} finally {
await tryDeleteFiles(smartCutSegmentsToConcat);
}
}
};
try {
return await pMap(segments, cutSegment, { concurrency: 1 });

@ -82,6 +82,17 @@ export async function havePermissionToReadFile(filePath: string) {
return true;
}
export const makeSourceFileAccessError = () => new UserFacingError(i18n.t('Source file no longer exists or is not accessible. Please check that it is still in its original location and that you have permission to access it.'));
export async function assertFileExists(filePath: string) {
try {
await access(filePath, R_OK);
} catch (err) {
console.error(err);
throw makeSourceFileAccessError();
}
}
export async function checkDirWriteAccess(dirPath: string) {
try {
await access(dirPath, W_OK);

Loading…
Cancel
Save