mirror of
https://git.netzspielplatz.de/docker-multiarch/openwrt-firmware-selector.git
synced 2025-11-08 17:19:25 +00:00
Handle error codes for bad package selection
Handles 409 and 422 HTTP codes for bad package selection. Shows popup for appropriate error message and gives a link for build logs. Fixes #12 Fixes #8 Signed-off-by: Sudhanshu Gautam <me@sudhanshug.com>
This commit is contained in:
parent
5e3b827489
commit
acdb7741e8
6 changed files with 123 additions and 65 deletions
|
|
@ -9,7 +9,7 @@ import {
|
|||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
function AlertDialog({open, cancelHandler, acceptHandler, text, title, cancelComponent, acceptComponent}) {
|
||||
function AlertDialog({open, cancelHandler, acceptHandler, body, title, cancelComponent, acceptComponent}) {
|
||||
return (
|
||||
<Dialog
|
||||
open={open}
|
||||
|
|
@ -21,17 +21,24 @@ function AlertDialog({open, cancelHandler, acceptHandler, text, title, cancelCom
|
|||
id="alert-dialog-title">{title}</DialogTitle>
|
||||
<DialogContent>
|
||||
<DialogContentText id="alert-dialog-description">
|
||||
{text}
|
||||
{body}
|
||||
</DialogContentText>
|
||||
</DialogContent>
|
||||
<DialogActions>
|
||||
<Button onClick={acceptHandler} color="primary">
|
||||
{acceptComponent}
|
||||
</Button>
|
||||
<Button onClick={cancelHandler} color="secondary"
|
||||
variant="contained" autoFocus>
|
||||
{cancelComponent}
|
||||
</Button>
|
||||
{
|
||||
acceptHandler && (
|
||||
<Button onClick={acceptHandler} color="primary">
|
||||
{acceptComponent}
|
||||
</Button>
|
||||
)
|
||||
}
|
||||
{
|
||||
cancelHandler && (
|
||||
<Button onClick={cancelHandler} color="secondary" variant="contained" autoFocus>
|
||||
{cancelComponent}
|
||||
</Button>
|
||||
)
|
||||
}
|
||||
</DialogActions>
|
||||
</Dialog>
|
||||
);
|
||||
|
|
@ -41,7 +48,7 @@ AlertDialog.propTypes = {
|
|||
open: PropTypes.bool,
|
||||
cancelHandler: PropTypes.func,
|
||||
acceptHandler: PropTypes.func,
|
||||
text: PropTypes.string,
|
||||
body: PropTypes.object,
|
||||
title: PropTypes.string,
|
||||
cancelComponent: PropTypes.elementType,
|
||||
acceptComponent: PropTypes.object,
|
||||
|
|
|
|||
|
|
@ -82,8 +82,9 @@ class Home extends React.Component {
|
|||
fuzzySet: null,
|
||||
showAdvanced: true,
|
||||
basicInterface: 0,
|
||||
errorDialogMessage: <></>,
|
||||
openErrorDialog: false,
|
||||
};
|
||||
basicInterface = 0;
|
||||
confirmingBuild = false;
|
||||
|
||||
dataService = new DataService();
|
||||
|
|
@ -258,7 +259,7 @@ class Home extends React.Component {
|
|||
const packageArray = this.state.packageName.split(/[,\n]+/);
|
||||
packageArray.forEach((package_name) => {
|
||||
package_name = package_name.replace(' ', '');
|
||||
if (package_name !== '') {
|
||||
if (package_name !== '' && packages.indexOf(package_name) === -1) {
|
||||
packages.push(package_name);
|
||||
}
|
||||
});
|
||||
|
|
@ -315,11 +316,22 @@ class Home extends React.Component {
|
|||
} else if (buildStatusResponse.status === 200) {
|
||||
await this.displayBuiltImageData(buildStatusResponse);
|
||||
resolve();
|
||||
} else if (buildStatusResponse.status === 409) {
|
||||
this.setState({
|
||||
openErrorDialog: true,
|
||||
errorDialogMessage: (
|
||||
<>
|
||||
{buildStatusResponse.data.error} <br />
|
||||
<a href={buildStatusResponse.data.error}>Build logs</a>
|
||||
</>
|
||||
),
|
||||
});
|
||||
resolve();
|
||||
} else {
|
||||
throw buildStatusResponse.data;
|
||||
}
|
||||
} catch (err) {
|
||||
reject(err);
|
||||
} catch (e) {
|
||||
reject(e);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
|
@ -336,6 +348,7 @@ class Home extends React.Component {
|
|||
builtImages: [],
|
||||
});
|
||||
let buildResponse = await this.dataService.buildImage(board, packages, target, version);
|
||||
console.log(buildResponse);
|
||||
if (buildResponse.status === 202 && buildResponse.data['request_hash'] !== undefined) {
|
||||
const request_hash = buildResponse.data['request_hash'];
|
||||
await sleep(buildStatusCheckInterval);
|
||||
|
|
@ -345,12 +358,34 @@ class Home extends React.Component {
|
|||
} else {
|
||||
throw buildResponse.data;
|
||||
}
|
||||
} catch (err) {
|
||||
this.setState({
|
||||
isBuilding: false,
|
||||
showUnexpectedErrorBar: true,
|
||||
});
|
||||
console.log(err);
|
||||
} catch (e) {
|
||||
if (e.response.status === 409) {
|
||||
this.setState({
|
||||
isBuilding: false,
|
||||
openErrorDialog: true,
|
||||
errorDialogMessage: (
|
||||
<>
|
||||
{e.response.data.error} <br />
|
||||
<a href={asu + e.response.data.log} target="_blank" rel="noopener noreferrer">Build logs</a>
|
||||
</>
|
||||
),
|
||||
});
|
||||
} else if (e.response.status === 422) {
|
||||
this.setState({
|
||||
isBuilding: false,
|
||||
openErrorDialog: true,
|
||||
errorDialogMessage: (
|
||||
<>
|
||||
{e.response.data.error}
|
||||
</>
|
||||
),
|
||||
});
|
||||
} else {
|
||||
this.setState({
|
||||
isBuilding: false,
|
||||
showUnexpectedErrorBar: true,
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -360,6 +395,12 @@ class Home extends React.Component {
|
|||
configChanged: true,
|
||||
});
|
||||
}
|
||||
|
||||
closeErrorDialog = () => {
|
||||
this.setState({
|
||||
openErrorDialog: false,
|
||||
});
|
||||
}
|
||||
|
||||
render() {
|
||||
const warning432 = this.state.showDeviceData && this.state.deviceLoaded &&
|
||||
|
|
@ -410,7 +451,7 @@ class Home extends React.Component {
|
|||
>
|
||||
{
|
||||
this.state.data.map((version, i) => (
|
||||
<MenuItem value={i} key={version.name}>
|
||||
<MenuItem value={i} key={version.revision}>
|
||||
<em>{version.name}</em>
|
||||
</MenuItem>
|
||||
))
|
||||
|
|
@ -501,28 +542,24 @@ class Home extends React.Component {
|
|||
<Grid item xs>
|
||||
<b>{this.props.t('Downloads')}: </b>
|
||||
{
|
||||
this.state.selection.device.images.map((image) => {
|
||||
return (
|
||||
<>
|
||||
<br />
|
||||
<Button
|
||||
key={image.name}
|
||||
className="download-button"
|
||||
href={asu_download +
|
||||
this.state.data[this.state.selection.version].path + '/targets/' +
|
||||
this.state.selection.device.target + '/' +
|
||||
image.name}
|
||||
color="primary"
|
||||
variant="contained"
|
||||
onClick={() => this.downloadingImageIndicatorShow()}
|
||||
>
|
||||
<CloudDownloadIcon
|
||||
className="download-icon"/>
|
||||
{image.name.split('-').reverse()[0].split('.')[0]}
|
||||
</Button>
|
||||
</>
|
||||
);
|
||||
})
|
||||
this.state.selection.device.images.map((image) =>
|
||||
<div key={image.name}>
|
||||
<Button
|
||||
className="download-button"
|
||||
href={asu_download +
|
||||
this.state.data[this.state.selection.version].path + '/targets/' +
|
||||
this.state.selection.device.target + '/' +
|
||||
image.name}
|
||||
color="primary"
|
||||
variant="contained"
|
||||
onClick={() => this.downloadingImageIndicatorShow()}
|
||||
>
|
||||
<CloudDownloadIcon
|
||||
className="download-icon"/>
|
||||
{image.name.split('-').reverse()[0].split('.')[0]}
|
||||
</Button>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
{
|
||||
|
|
@ -538,17 +575,15 @@ class Home extends React.Component {
|
|||
<Paper elevation={0} className="package-list-input">
|
||||
<div>
|
||||
{
|
||||
this.state.packages.map((package_name, i) => {
|
||||
return (
|
||||
this.state.packages.map((package_name, i) =>
|
||||
<Chip className="package"
|
||||
key={package_name}
|
||||
key={package_name + i}
|
||||
size="small"
|
||||
onDelete={() => this.deletePackage(
|
||||
i)}
|
||||
label={package_name}
|
||||
/>
|
||||
);
|
||||
})
|
||||
)
|
||||
}
|
||||
<Tooltip
|
||||
title={<span>Use comma or new line separated array. <br/>Press enter to apply.</span>}>
|
||||
|
|
@ -581,8 +616,11 @@ class Home extends React.Component {
|
|||
{this.props.t('Cancel')}
|
||||
</Button>
|
||||
|
||||
|
||||
<CircularProgress size={20} style={{verticalAlign: 'middle'}}/>
|
||||
|
||||
Building image
|
||||
|
||||
{
|
||||
this.state.queuePosition !== -1 && (
|
||||
<span> (Position in queue: {this.state.queuePosition}) </span>
|
||||
|
|
@ -651,17 +689,27 @@ class Home extends React.Component {
|
|||
cancelHandler={this.closeConfirmBuildDialog}
|
||||
acceptHandler={this.buildImage}
|
||||
open={this.confirmingBuild}
|
||||
text={this.props.t(
|
||||
'Building image requires computation resources, so we would request you to check if this selection is what you want')}
|
||||
body={
|
||||
<>
|
||||
{this.props.t('Building image requires computation resources, so we would request you to check if this selection is what you want')}
|
||||
</>
|
||||
}
|
||||
title={this.props.t(
|
||||
'Please confirm that you want to perform this action')}
|
||||
cancelComponent={this.props.t('Cancel')}
|
||||
acceptComponent={
|
||||
<>
|
||||
{this.props.t('Build')} <BuildIcon/>
|
||||
</>
|
||||
<>
|
||||
{this.props.t('Build')} <BuildIcon/>
|
||||
</>
|
||||
}
|
||||
/>
|
||||
<AlertDialog
|
||||
cancelHandler={this.closeErrorDialog}
|
||||
open={this.state.openErrorDialog}
|
||||
body={this.state.errorDialogMessage}
|
||||
title={this.props.t('There is an error with the packages you selected')}
|
||||
cancelComponent={this.props.t('Dismiss')}
|
||||
/>
|
||||
<Container className="home-container">
|
||||
<Paper className="home-container-paper">
|
||||
{this.state.devicesLoaded ? onLoad : notLoaded}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ $bg-color: #f0f0f0;
|
|||
|
||||
.home-container {
|
||||
margin-top: 30px;
|
||||
margin-bottom: 100px;
|
||||
|
||||
.home-container-paper {
|
||||
padding: 30px;
|
||||
|
|
@ -76,7 +77,7 @@ $bg-color: #f0f0f0;
|
|||
}
|
||||
|
||||
.download-button {
|
||||
margin-top: 10px;
|
||||
margin-top: 17px;
|
||||
|
||||
.download-icon {
|
||||
margin-right: 10px;
|
||||
|
|
|
|||
|
|
@ -22,6 +22,8 @@
|
|||
"OpenWrt Firmware Selector Wizard": "OpenWrt Firmware Selector Wizard",
|
||||
"Download OpenWrt firmware for your device!": "Laden Sie die OpenWrt-Firmware für Ihr Gerät herunter!",
|
||||
"Target": "Ziel",
|
||||
"Dismiss": "Entlassen",
|
||||
"There is an error with the packages you selected": "Bei den ausgewählten Paketen ist ein Fehler aufgetreten",
|
||||
"Downloads": "Herunterladen",
|
||||
"Please use the input below to download firmware for your device!": "Bitte benutzen Sie den unten stehenden Eingang, um die Firmware für Ihr Gerät herunterzuladen!"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,6 +22,8 @@
|
|||
"OpenWrt Firmware Selector Wizard": "OpenWrt Firmware Selector Wizard",
|
||||
"Download OpenWrt firmware for your device!": "Download OpenWrt firmware for your device!",
|
||||
"Target": "Target",
|
||||
"Dismiss": "Dismiss",
|
||||
"There is an error with the packages you selected": "There is an error with the packages you selected",
|
||||
"Downloads": "Downloads",
|
||||
"Please use the input below to download firmware for your device!": "Please use the input below to download firmware for your device!"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,17 +13,15 @@ class DataService {
|
|||
|
||||
getDevicePackages = (version, target, profile) => axios.get(base_api + 'packages_image?distro=openwrt&version=' + version.toLowerCase() + '&target=' + target + '&profile=' + profile.toLowerCase());
|
||||
|
||||
buildImage = (board, packages, target, version) => {
|
||||
return axios.post(base_api + 'build-request', {
|
||||
profile: board,
|
||||
board,
|
||||
defaults: '',
|
||||
distro: 'openwrt',
|
||||
packages,
|
||||
target,
|
||||
version,
|
||||
});
|
||||
};
|
||||
buildImage = (board, packages, target, version) => axios.post(base_api + 'build-request', {
|
||||
profile: board,
|
||||
board,
|
||||
defaults: '',
|
||||
distro: 'openwrt',
|
||||
packages,
|
||||
target,
|
||||
version,
|
||||
});
|
||||
|
||||
buildStatusCheck = (request_hash) => axios.get(base_api + 'build-request/' + request_hash);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue