Improve flashing error handling

Changelog-entry: Improve flashing error handling
Change-type: patch
This commit is contained in:
Alexis Svinartchouk 2020-11-25 18:21:45 +01:00
parent fa593e33d1
commit 2158e20380
3 changed files with 52 additions and 21 deletions

View File

@ -127,12 +127,12 @@ export function FlashResults({
};
} & FlexProps) {
const [showErrorsInfo, setShowErrorsInfo] = React.useState(false);
const allFailed = results.devices.successful === 0;
const allFailed = !skip && results.devices.successful === 0;
const someFailed = results.devices.failed !== 0 || errors.length !== 0;
const effectiveSpeed = _.round(
bytesToMegabytes(
results.sourceMetadata.size /
(results.bytesWritten / results.averageFlashingSpeed),
(results.sourceMetadata.blockmappedSize / results.averageFlashingSpeed),
),
1,
);
@ -155,7 +155,7 @@ export function FlashResults({
<Txt>{middleEllipsis(image, 24)}</Txt>
</Flex>
<Txt fontSize={24} color="#fff" mb="17px">
Flash Complete!
Flash {allFailed ? 'Failed' : 'Complete'}!
</Txt>
{skip ? <Txt color="#7e8085">Validation has been skipped</Txt> : null}
</Flex>

View File

@ -17,7 +17,7 @@
import { Drive as DrivelistDrive } from 'drivelist';
import * as electron from 'electron';
import * as sdk from 'etcher-sdk';
import * as _ from 'lodash';
import { Dictionary } from 'lodash';
import * as ipc from 'node-ipc';
import * as os from 'os';
import * as path from 'path';
@ -133,6 +133,14 @@ function writerEnv() {
interface FlashResults {
skip?: boolean;
cancelled?: boolean;
results?: {
bytesWritten: number;
devices: {
failed: number;
successful: number;
};
errors: Error[];
};
}
async function performWrite(
@ -177,10 +185,12 @@ async function performWrite(
});
ipc.server.on('done', (event) => {
event.results.errors = _.map(event.results.errors, (data) => {
return errors.fromJSON(data);
});
_.merge(flashResults, event);
event.results.errors = event.results.errors.map(
(data: Dictionary<any> & { message: string }) => {
return errors.fromJSON(data);
},
);
flashResults.results = event.results;
});
ipc.server.on('abort', () => {
@ -209,7 +219,7 @@ async function performWrite(
const argv = writerArgv();
ipc.server.on('start', async () => {
console.log(`Elevating command: ${_.join(argv, ' ')}`);
console.log(`Elevating command: ${argv.join(' ')}`);
const env = writerEnv();
try {
const results = await permissions.elevateCommand(argv, {
@ -231,11 +241,11 @@ async function performWrite(
}
console.log('Flash results', flashResults);
// This likely means the child died halfway through
// The flash wasn't cancelled and we didn't get a 'done' event
if (
!flashResults.cancelled &&
!flashResults.skip &&
!_.get(flashResults, ['results', 'bytesWritten'])
flashResults.results === undefined
) {
reject(
errors.createUserError({

View File

@ -59,6 +59,27 @@ const getErrorMessageFromCode = (errorCode: string) => {
return '';
};
function notifySuccess(
iconPath: string,
basename: string,
drives: any,
devices: { successful: number; failed: number },
) {
notification.send(
'Flash complete!',
messages.info.flashComplete(basename, drives, devices),
iconPath,
);
}
function notifyFailure(iconPath: string, basename: string, drives: any) {
notification.send(
'Oops! Looks like the flash failed.',
messages.error.flashFailure(basename, drives),
iconPath,
);
}
async function flashImageToDrive(
isFlashing: boolean,
goToSuccess: () => void,
@ -84,20 +105,20 @@ async function flashImageToDrive(
if (!flashState.wasLastFlashCancelled()) {
const {
results = { devices: { successful: 0, failed: 0 } },
skip,
cancelled,
} = flashState.getFlashResults();
notification.send(
'Flash complete!',
messages.info.flashComplete(basename, drives as any, results.devices),
iconPath,
);
if (!skip && !cancelled) {
if (results.devices.successful > 0) {
notifySuccess(iconPath, basename, drives, results.devices);
} else {
notifyFailure(iconPath, basename, drives);
}
}
goToSuccess();
}
} catch (error) {
notification.send(
'Oops! Looks like the flash failed.',
messages.error.flashFailure(path.basename(image.path), drives),
iconPath,
);
notifyFailure(iconPath, basename, drives);
let errorMessage = getErrorMessageFromCode(error.code);
if (!errorMessage) {
error.image = basename;