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:
Sudhanshu Gautam 2019-08-26 01:15:05 +05:30
parent 5e3b827489
commit acdb7741e8
6 changed files with 123 additions and 65 deletions

View file

@ -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,

View file

@ -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,
});
}
}
};
@ -361,6 +396,12 @@ class Home extends React.Component {
});
}
closeErrorDialog = () => {
this.setState({
openErrorDialog: false,
});
}
render() {
const warning432 = this.state.showDeviceData && this.state.deviceLoaded &&
parseInt(
@ -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>
)
}
&nbsp;
{
@ -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>
&nbsp;
&nbsp;
<CircularProgress size={20} style={{verticalAlign: 'middle'}}/>
&nbsp;
Building image
&nbsp;
{
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')} &nbsp; <BuildIcon/>
</>
<>
{this.props.t('Build')} &nbsp; <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}

View file

@ -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;

View file

@ -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!"
}

View file

@ -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!"
}

View file

@ -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);