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