From acdb7741e830cc07911ce1f729042418bfb01d27 Mon Sep 17 00:00:00 2001 From: Sudhanshu Gautam Date: Mon, 26 Aug 2019 01:15:05 +0530 Subject: [PATCH] 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 --- src/components/alert-dialog.js | 27 ++++--- src/containers/home/home.js | 134 ++++++++++++++++++++++----------- src/containers/home/home.scss | 3 +- src/locales/de.json | 2 + src/locales/en.json | 2 + src/services/data.js | 20 +++-- 6 files changed, 123 insertions(+), 65 deletions(-) diff --git a/src/components/alert-dialog.js b/src/components/alert-dialog.js index 19eb17c..e046287 100644 --- a/src/components/alert-dialog.js +++ b/src/components/alert-dialog.js @@ -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 ( {title} - {text} + {body} - - + { + acceptHandler && ( + + ) + } + { + cancelHandler && ( + + ) + } ); @@ -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, diff --git a/src/containers/home/home.js b/src/containers/home/home.js index c51379c..c718fba 100644 --- a/src/containers/home/home.js +++ b/src/containers/home/home.js @@ -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}
+ Build logs + + ), + }); + 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}
+ Build logs + + ), + }); + } 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) => ( - + {version.name} )) @@ -501,28 +542,24 @@ class Home extends React.Component { {this.props.t('Downloads')}: { - this.state.selection.device.images.map((image) => { - return ( - <> -
- - - ); - }) + this.state.selection.device.images.map((image) => +
+ +
+ ) }   { @@ -538,17 +575,15 @@ class Home extends React.Component {
{ - this.state.packages.map((package_name, i) => { - return ( + this.state.packages.map((package_name, i) => this.deletePackage( i)} label={package_name} /> - ); - }) + ) } Use comma or new line separated array.
Press enter to apply.}> @@ -581,8 +616,11 @@ class Home extends React.Component { {this.props.t('Cancel')}   +   +   Building image +   { this.state.queuePosition !== -1 && ( (Position in queue: {this.state.queuePosition}) @@ -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')}   - + <> + {this.props.t('Build')}   + } /> + {this.state.devicesLoaded ? onLoad : notLoaded} diff --git a/src/containers/home/home.scss b/src/containers/home/home.scss index 1f09e5e..25ec0d9 100644 --- a/src/containers/home/home.scss +++ b/src/containers/home/home.scss @@ -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; diff --git a/src/locales/de.json b/src/locales/de.json index b5b942b..6bb6da7 100644 --- a/src/locales/de.json +++ b/src/locales/de.json @@ -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!" } diff --git a/src/locales/en.json b/src/locales/en.json index 4a72133..c861fc6 100644 --- a/src/locales/en.json +++ b/src/locales/en.json @@ -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!" } diff --git a/src/services/data.js b/src/services/data.js index 58609fd..0f8e469 100644 --- a/src/services/data.js +++ b/src/services/data.js @@ -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);