mirror of
https://github.com/balena-io/etcher.git
synced 2025-07-28 05:36:34 +00:00
Improve flashing error handling
Changelog-entry: Improve flashing error handling Change-type: patch
This commit is contained in:
parent
fa593e33d1
commit
2158e20380
@ -127,12 +127,12 @@ export function FlashResults({
|
|||||||
};
|
};
|
||||||
} & FlexProps) {
|
} & FlexProps) {
|
||||||
const [showErrorsInfo, setShowErrorsInfo] = React.useState(false);
|
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 someFailed = results.devices.failed !== 0 || errors.length !== 0;
|
||||||
const effectiveSpeed = _.round(
|
const effectiveSpeed = _.round(
|
||||||
bytesToMegabytes(
|
bytesToMegabytes(
|
||||||
results.sourceMetadata.size /
|
results.sourceMetadata.size /
|
||||||
(results.bytesWritten / results.averageFlashingSpeed),
|
(results.sourceMetadata.blockmappedSize / results.averageFlashingSpeed),
|
||||||
),
|
),
|
||||||
1,
|
1,
|
||||||
);
|
);
|
||||||
@ -155,7 +155,7 @@ export function FlashResults({
|
|||||||
<Txt>{middleEllipsis(image, 24)}</Txt>
|
<Txt>{middleEllipsis(image, 24)}</Txt>
|
||||||
</Flex>
|
</Flex>
|
||||||
<Txt fontSize={24} color="#fff" mb="17px">
|
<Txt fontSize={24} color="#fff" mb="17px">
|
||||||
Flash Complete!
|
Flash {allFailed ? 'Failed' : 'Complete'}!
|
||||||
</Txt>
|
</Txt>
|
||||||
{skip ? <Txt color="#7e8085">Validation has been skipped</Txt> : null}
|
{skip ? <Txt color="#7e8085">Validation has been skipped</Txt> : null}
|
||||||
</Flex>
|
</Flex>
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
import { Drive as DrivelistDrive } from 'drivelist';
|
import { Drive as DrivelistDrive } from 'drivelist';
|
||||||
import * as electron from 'electron';
|
import * as electron from 'electron';
|
||||||
import * as sdk from 'etcher-sdk';
|
import * as sdk from 'etcher-sdk';
|
||||||
import * as _ from 'lodash';
|
import { Dictionary } from 'lodash';
|
||||||
import * as ipc from 'node-ipc';
|
import * as ipc from 'node-ipc';
|
||||||
import * as os from 'os';
|
import * as os from 'os';
|
||||||
import * as path from 'path';
|
import * as path from 'path';
|
||||||
@ -133,6 +133,14 @@ function writerEnv() {
|
|||||||
interface FlashResults {
|
interface FlashResults {
|
||||||
skip?: boolean;
|
skip?: boolean;
|
||||||
cancelled?: boolean;
|
cancelled?: boolean;
|
||||||
|
results?: {
|
||||||
|
bytesWritten: number;
|
||||||
|
devices: {
|
||||||
|
failed: number;
|
||||||
|
successful: number;
|
||||||
|
};
|
||||||
|
errors: Error[];
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
async function performWrite(
|
async function performWrite(
|
||||||
@ -177,10 +185,12 @@ async function performWrite(
|
|||||||
});
|
});
|
||||||
|
|
||||||
ipc.server.on('done', (event) => {
|
ipc.server.on('done', (event) => {
|
||||||
event.results.errors = _.map(event.results.errors, (data) => {
|
event.results.errors = event.results.errors.map(
|
||||||
|
(data: Dictionary<any> & { message: string }) => {
|
||||||
return errors.fromJSON(data);
|
return errors.fromJSON(data);
|
||||||
});
|
},
|
||||||
_.merge(flashResults, event);
|
);
|
||||||
|
flashResults.results = event.results;
|
||||||
});
|
});
|
||||||
|
|
||||||
ipc.server.on('abort', () => {
|
ipc.server.on('abort', () => {
|
||||||
@ -209,7 +219,7 @@ async function performWrite(
|
|||||||
const argv = writerArgv();
|
const argv = writerArgv();
|
||||||
|
|
||||||
ipc.server.on('start', async () => {
|
ipc.server.on('start', async () => {
|
||||||
console.log(`Elevating command: ${_.join(argv, ' ')}`);
|
console.log(`Elevating command: ${argv.join(' ')}`);
|
||||||
const env = writerEnv();
|
const env = writerEnv();
|
||||||
try {
|
try {
|
||||||
const results = await permissions.elevateCommand(argv, {
|
const results = await permissions.elevateCommand(argv, {
|
||||||
@ -231,11 +241,11 @@ async function performWrite(
|
|||||||
}
|
}
|
||||||
console.log('Flash results', flashResults);
|
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 (
|
if (
|
||||||
!flashResults.cancelled &&
|
!flashResults.cancelled &&
|
||||||
!flashResults.skip &&
|
!flashResults.skip &&
|
||||||
!_.get(flashResults, ['results', 'bytesWritten'])
|
flashResults.results === undefined
|
||||||
) {
|
) {
|
||||||
reject(
|
reject(
|
||||||
errors.createUserError({
|
errors.createUserError({
|
||||||
|
@ -59,6 +59,27 @@ const getErrorMessageFromCode = (errorCode: string) => {
|
|||||||
return '';
|
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(
|
async function flashImageToDrive(
|
||||||
isFlashing: boolean,
|
isFlashing: boolean,
|
||||||
goToSuccess: () => void,
|
goToSuccess: () => void,
|
||||||
@ -84,20 +105,20 @@ async function flashImageToDrive(
|
|||||||
if (!flashState.wasLastFlashCancelled()) {
|
if (!flashState.wasLastFlashCancelled()) {
|
||||||
const {
|
const {
|
||||||
results = { devices: { successful: 0, failed: 0 } },
|
results = { devices: { successful: 0, failed: 0 } },
|
||||||
|
skip,
|
||||||
|
cancelled,
|
||||||
} = flashState.getFlashResults();
|
} = flashState.getFlashResults();
|
||||||
notification.send(
|
if (!skip && !cancelled) {
|
||||||
'Flash complete!',
|
if (results.devices.successful > 0) {
|
||||||
messages.info.flashComplete(basename, drives as any, results.devices),
|
notifySuccess(iconPath, basename, drives, results.devices);
|
||||||
iconPath,
|
} else {
|
||||||
);
|
notifyFailure(iconPath, basename, drives);
|
||||||
|
}
|
||||||
|
}
|
||||||
goToSuccess();
|
goToSuccess();
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
notification.send(
|
notifyFailure(iconPath, basename, drives);
|
||||||
'Oops! Looks like the flash failed.',
|
|
||||||
messages.error.flashFailure(path.basename(image.path), drives),
|
|
||||||
iconPath,
|
|
||||||
);
|
|
||||||
let errorMessage = getErrorMessageFromCode(error.code);
|
let errorMessage = getErrorMessageFromCode(error.code);
|
||||||
if (!errorMessage) {
|
if (!errorMessage) {
|
||||||
error.image = basename;
|
error.image = basename;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user