mirror of
https://github.com/balena-io/etcher.git
synced 2025-04-24 07:17:18 +00:00
Use async/await in flash.js
Avoid a rare race condition leading to "Error: There is already a flash in progress" messages Changelog-entry: Avoid "Error: There is already a flash in progress" errors Change-type: patch
This commit is contained in:
parent
ec015da795
commit
34c98d1dcd
@ -289,7 +289,7 @@ rules:
|
||||
- error
|
||||
- anonymous: always
|
||||
named: always
|
||||
asyncArrow: never
|
||||
asyncArrow: always
|
||||
template-tag-spacing:
|
||||
- error
|
||||
- always
|
||||
|
@ -31,7 +31,6 @@ const availableDrives = require('../../../models/available-drives')
|
||||
const selection = require('../../../models/selection-state')
|
||||
|
||||
module.exports = function (
|
||||
$q,
|
||||
$state,
|
||||
$timeout,
|
||||
FlashErrorModalService,
|
||||
@ -67,39 +66,34 @@ module.exports = function (
|
||||
*
|
||||
* @param {Array<Object>} drives - list of drive objects
|
||||
* @param {Object} image - image object
|
||||
* @returns {Promise}
|
||||
* @returns {Promise<Boolean>}
|
||||
*
|
||||
* @example
|
||||
* displayTailoredWarning(drives, image).then(() => {
|
||||
* console.log('Continue pressed')
|
||||
* }).catch(() => {
|
||||
* console.log('Change pressed')
|
||||
* displayTailoredWarning(drives, image).then((ok) => {
|
||||
* if (ok) {
|
||||
* console.log('No warning was shown or continue was pressed')
|
||||
* } else {
|
||||
* console.log('Change was pressed')
|
||||
* }
|
||||
* })
|
||||
*/
|
||||
const displayTailoredWarning = (drives, image) => {
|
||||
const warningMessages = _.reduce(drives, (accumMessages, drive) => {
|
||||
const displayTailoredWarning = async (drives, image) => {
|
||||
const warningMessages = []
|
||||
for (const drive of drives) {
|
||||
if (constraints.isDriveSizeLarge(drive)) {
|
||||
return accumMessages.concat(messages.warning.largeDriveSize(drive))
|
||||
warningMessages.push(messages.warning.largeDriveSize(drive))
|
||||
} else if (!constraints.isDriveSizeRecommended(drive, image)) {
|
||||
return accumMessages.concat(messages.warning.unrecommendedDriveSize(image, drive))
|
||||
warningMessages.push(messages.warning.unrecommendedDriveSize(image, drive))
|
||||
}
|
||||
|
||||
return accumMessages
|
||||
}, [])
|
||||
|
||||
if (!warningMessages.length) {
|
||||
// TODO(Shou): we should consider adding the same warning dialog for system drives and remove unsafe mode
|
||||
return $q.resolve()
|
||||
}
|
||||
|
||||
return confirmationWarningModal(warningMessages).then((value) => {
|
||||
if (!value) {
|
||||
DriveSelectorService.open()
|
||||
return $q.reject()
|
||||
}
|
||||
if (!warningMessages.length) {
|
||||
return true
|
||||
}
|
||||
|
||||
return $q.resolve()
|
||||
})
|
||||
return confirmationWarningModal(warningMessages)
|
||||
}
|
||||
|
||||
/**
|
||||
@ -118,35 +112,36 @@ module.exports = function (
|
||||
* '/dev/disk5'
|
||||
* ])
|
||||
*/
|
||||
this.flashImageToDrive = () => {
|
||||
const image = selection.getImage()
|
||||
this.flashImageToDrive = async () => {
|
||||
const devices = selection.getSelectedDevices()
|
||||
|
||||
if (flashState.isFlashing()) {
|
||||
return
|
||||
}
|
||||
|
||||
const image = selection.getImage()
|
||||
const drives = _.filter(availableDrives.getDrives(), (drive) => {
|
||||
return _.includes(devices, drive.device)
|
||||
})
|
||||
|
||||
const hasDangerStatus = constraints.hasListDriveImageCompatibilityStatus(drives, image)
|
||||
if (hasDangerStatus) {
|
||||
if (!(await displayTailoredWarning(drives, image))) {
|
||||
DriveSelectorService.open()
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
const userConfirm = hasDangerStatus ? _.partial(displayTailoredWarning, drives, image) : $q.resolve
|
||||
if (flashState.isFlashing()) {
|
||||
return
|
||||
}
|
||||
|
||||
// Trigger Angular digests along with store updates, as the flash state
|
||||
// updates. Without this there is essentially no progress to watch.
|
||||
const unsubscribe = store.observe($timeout)
|
||||
|
||||
// Stop scanning drives when flashing
|
||||
// otherwise Windows throws EPERM
|
||||
driveScanner.stop()
|
||||
|
||||
const iconPath = '../../../assets/icon.png'
|
||||
|
||||
userConfirm().then(() => {
|
||||
// Stop scanning drives when flashing
|
||||
// otherwise Windows throws EPERM
|
||||
driveScanner.stop()
|
||||
|
||||
return imageWriter.flash(image.path, drives)
|
||||
}).then(() => {
|
||||
try {
|
||||
await imageWriter.flash(image.path, drives)
|
||||
if (!flashState.wasLastFlashCancelled()) {
|
||||
const flashResults = flashState.getFlashResults()
|
||||
notification.send('Flash complete!', {
|
||||
@ -155,7 +150,7 @@ module.exports = function (
|
||||
})
|
||||
$state.go('success')
|
||||
}
|
||||
}).catch((error) => {
|
||||
} catch (error) {
|
||||
// When flashing is cancelled before starting above there is no error
|
||||
if (!error) {
|
||||
return
|
||||
@ -183,11 +178,11 @@ module.exports = function (
|
||||
FlashErrorModalService.show(messages.error.genericFlashError())
|
||||
exceptionReporter.report(error)
|
||||
}
|
||||
}).finally(() => {
|
||||
} finally {
|
||||
availableDrives.setDrives([])
|
||||
driveScanner.start()
|
||||
unsubscribe()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
Loading…
x
Reference in New Issue
Block a user