Skip to content

Commit 3bdeb9a

Browse files
Implement API fetch error display for select dropdown. #8668
1 parent f64b59e commit 3bdeb9a

File tree

2 files changed

+110
-61
lines changed

2 files changed

+110
-61
lines changed

web/pgadmin/misc/cloud/google/__init__.py

Lines changed: 92 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,9 @@ def get_projects():
159159
"""
160160
if 'google' in session and 'google_obj' in session['google']:
161161
google_obj = pickle.loads(session['google']['google_obj'])
162-
projects_list = google_obj.get_projects()
162+
projects_list,error = google_obj.get_projects()
163+
if error:
164+
return bad_request(errormsg=error)
163165
return make_json_response(data=projects_list)
164166

165167

@@ -175,8 +177,10 @@ def get_regions(project_id):
175177
if 'google' in session and 'google_obj' in session['google'] \
176178
and project_id:
177179
google_obj = pickle.loads(session['google']['google_obj'])
178-
regions_list = google_obj.get_regions(project_id)
180+
regions_list,error = google_obj.get_regions(project_id)
179181
session['google']['google_obj'] = pickle.dumps(google_obj, -1)
182+
if error:
183+
return bad_request(errormsg=error)
180184
return make_json_response(data=regions_list)
181185
else:
182186
return make_json_response(data=[])
@@ -216,7 +220,10 @@ def get_instance_types(project_id, region, instance_class):
216220
google_obj = pickle.loads(session['google']['google_obj'])
217221
instance_types_dict = google_obj.get_instance_types(
218222
project_id, region)
219-
instance_types_list = instance_types_dict.get(instance_class, [])
223+
instance_types_list, error = (
224+
instance_types_dict.get(instance_class, []))
225+
if error:
226+
return bad_request(errormsg=error)
220227
return make_json_response(data=instance_types_list)
221228
else:
222229
return make_json_response(data=[])
@@ -232,7 +239,9 @@ def get_database_versions():
232239
"""
233240
if 'google' in session and 'google_obj' in session['google']:
234241
google_obj = pickle.loads(session['google']['google_obj'])
235-
db_version_list = google_obj.get_database_versions()
242+
db_version_list, error = google_obj.get_database_versions()
243+
if error:
244+
return bad_request(errormsg=error)
236245
return make_json_response(data=db_version_list)
237246
else:
238247
return make_json_response(data=[])
@@ -431,16 +440,22 @@ def get_projects(self):
431440
:return:
432441
"""
433442
projects = []
443+
error = None
434444
credentials = self._get_credentials(self._scopes)
435445
service = discovery.build('cloudresourcemanager',
436446
self._cloud_resource_manager_api_version,
437447
credentials=credentials)
438-
req = service.projects().list()
439-
res = req.execute()
440-
for project in res.get('projects', []):
441-
projects.append({'label': project['projectId'],
442-
'value': project['projectId']})
443-
return projects
448+
try:
449+
req = service.projects().list()
450+
res = req.execute()
451+
for project in res.get('projects', []):
452+
projects.append({'label': project['projectId'],
453+
'value': project['projectId']})
454+
except HttpError as e:
455+
error = e.reason
456+
except Exception as e:
457+
error = str(e)
458+
return projects, error
444459

445460
def get_regions(self, project):
446461
"""
@@ -453,20 +468,23 @@ def get_regions(self, project):
453468
service = discovery.build('compute',
454469
self._compute_api_version,
455470
credentials=credentials)
471+
error = None
456472
try:
457473
req = service.regions().list(project=project)
458474
res = req.execute()
459-
except HttpError:
460-
self._regions = []
461-
return self._regions
462-
for item in res.get('items', []):
463-
region_name = item['name']
464-
self._regions.append({'label': region_name, 'value': region_name})
465-
region_zones = item.get('zones', [])
466-
region_zones = list(
467-
map(lambda region: region.split('/')[-1], region_zones))
468-
self._availability_zones[region_name] = region_zones
469-
return self._regions
475+
for item in res.get('items', []):
476+
region_name = item['name']
477+
self._regions.append(
478+
{'label': region_name, 'value': region_name})
479+
region_zones = item.get('zones', [])
480+
region_zones = list(
481+
map(lambda region: region.split('/')[-1], region_zones))
482+
self._availability_zones[region_name] = region_zones
483+
except HttpError as e:
484+
error = e.reason
485+
except Exception as e:
486+
error = str(e)
487+
return self._regions, error
470488

471489
def get_availability_zones(self, region):
472490
"""
@@ -489,35 +507,47 @@ def get_instance_types(self, project, region):
489507
standard_instances = []
490508
shared_instances = []
491509
high_mem = []
510+
instance_types = {}
511+
error = None
492512
credentials = self._get_credentials(self._scopes)
493513
service = discovery.build('sqladmin',
494514
self._sqladmin_api_version,
495515
credentials=credentials)
496-
req = service.tiers().list(project=project)
497-
res = req.execute()
498-
for item in res.get('items', []):
499-
if region in item.get('region', []):
500-
if item['tier'].find('standard') != -1:
501-
vcpu = item['tier'].split('-')[-1]
502-
mem = round(int(item['RAM']) / (1024 * 1024))
503-
label = vcpu + ' vCPU, ' + str(round(mem / 1024)) + ' GB'
504-
value = 'db-custom-' + str(vcpu) + '-' + str(mem)
505-
standard_instances.append({'label': label, 'value': value})
506-
elif item['tier'].find('highmem') != -1:
507-
vcpu = item['tier'].split('-')[-1]
508-
mem = round(int(item['RAM']) / (1024 * 1024))
509-
label = vcpu + ' vCPU, ' + str(round(mem / 1024)) + ' GB'
510-
value = 'db-custom-' + str(vcpu) + '-' + str(mem)
511-
high_mem.append({'label': label, 'value': value})
512-
else:
513-
label = '1 vCPU, ' + str(
514-
round((int(item['RAM']) / 1073741824), 2)) + ' GB'
515-
value = item['tier']
516-
shared_instances.append({'label': label, 'value': value})
517-
instance_types = {'standard': standard_instances,
518-
'highmem': high_mem,
519-
'shared': shared_instances}
520-
return instance_types
516+
try:
517+
req = service.tiers().list(project=project)
518+
res = req.execute()
519+
for item in res.get('items', []):
520+
if region in item.get('region', []):
521+
if item['tier'].find('standard') != -1:
522+
vcpu = item['tier'].split('-')[-1]
523+
mem = round(int(item['RAM']) / (1024 * 1024))
524+
label = (
525+
vcpu + ' vCPU, ' + str(round(mem / 1024)) + ' GB')
526+
value = 'db-custom-' + str(vcpu) + '-' + str(mem)
527+
standard_instances.append(
528+
{'label': label, 'value': value})
529+
elif item['tier'].find('highmem') != -1:
530+
vcpu = item['tier'].split('-')[-1]
531+
mem = round(int(item['RAM']) / (1024 * 1024))
532+
label = \
533+
(vcpu + ' vCPU, ' + str(round(mem / 1024)) + ' GB')
534+
value = 'db-custom-' + str(vcpu) + '-' + str(mem)
535+
high_mem.append(
536+
{'label': label, 'value': value})
537+
else:
538+
label = '1 vCPU, ' + str(
539+
round((int(item['RAM']) / 1073741824), 2)) + ' GB'
540+
value = item['tier']
541+
shared_instances.append(
542+
{'label': label, 'value': value})
543+
instance_types = {'standard': standard_instances,
544+
'highmem': high_mem,
545+
'shared': shared_instances}
546+
except HttpError as e:
547+
error = e.reason
548+
except Exception as e:
549+
error = str(e)
550+
return instance_types, error
521551

522552
def get_database_versions(self):
523553
"""
@@ -526,17 +556,23 @@ def get_database_versions(self):
526556
"""
527557
pg_database_versions = []
528558
database_versions = []
559+
error = None
529560
credentials = self._get_credentials(self._scopes)
530561
service = discovery.build('sqladmin',
531562
self._sqladmin_api_version,
532563
credentials=credentials)
533-
req = service.flags().list()
534-
res = req.execute()
535-
for item in res.get('items', []):
536-
if item.get('name', '') == 'max_parallel_workers':
537-
pg_database_versions = item.get('appliesTo', [])
538-
for version in pg_database_versions:
539-
label = (version.title().split('_')[0])[0:7] \
540-
+ 'SQL ' + version.split('_')[1]
541-
database_versions.append({'label': label, 'value': version})
542-
return database_versions
564+
try:
565+
req = service.flags().list()
566+
res = req.execute()
567+
for item in res.get('items', []):
568+
if item.get('name', '') == 'max_parallel_workers':
569+
pg_database_versions = item.get('appliesTo', [])
570+
for version in pg_database_versions:
571+
label = (version.title().split('_')[0])[0:7] \
572+
+ 'SQL ' + version.split('_')[1]
573+
database_versions.append({'label': label, 'value': version})
574+
except HttpError as e:
575+
error = e.reason
576+
except Exception as e:
577+
error = str(e)
578+
return database_versions, error

web/pgadmin/static/js/components/FormComponents.jsx

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ const StyledGrid = styled(Grid)(({theme}) => ({
121121
}));
122122

123123
/* Wrapper on any form component to add label, error indicator and help message */
124-
export function FormInput({ children, error, className, label, helpMessage, required, testcid, lid, withContainer=true, labelGridBasis=3, controlGridBasis=9, labelTooltip='' }) {
124+
export function FormInput({ children, error, className, label, helpMessage, required, testcid, lid, withContainer=true, labelGridBasis=3, controlGridBasis=9, labelTooltip='', errorMessage='' }) {
125125

126126
const cid = testcid || _.uniqueId('c');
127127
const helpid = `h${cid}`;
@@ -163,6 +163,7 @@ export function FormInput({ children, error, className, label, helpMessage, requ
163163
{React.cloneElement(children, { cid, helpid })}
164164
</FormControl>
165165
<FormHelperText id={helpid} variant="outlined">{HTMLReactParse(helpMessage || '')}</FormHelperText>
166+
{errorMessage && <FormHelperText variant="outlined" error= {true} style={{ wordBreak: 'break-word', overflowWrap: 'anywhere' }}>{HTMLReactParse(errorMessage)}</FormHelperText> }
166167
</Grid>
167168
</StyledGrid>
168169
);
@@ -179,7 +180,8 @@ FormInput.propTypes = {
179180
withContainer: PropTypes.bool,
180181
labelGridBasis: PropTypes.number,
181182
controlGridBasis: PropTypes.number,
182-
labelTooltip: PropTypes.string
183+
labelTooltip: PropTypes.string,
184+
errorMessage: PropTypes.string
183185
};
184186

185187
export function InputSQL({ value, options={}, onChange, className, controlProps, inputRef, ...props }) {
@@ -917,7 +919,7 @@ InputSelectNonSearch.propTypes = {
917919
};
918920

919921
export const InputSelect = forwardRef(({
920-
cid, helpid, onChange, options, readonly = false, value, controlProps = {}, optionsLoaded, optionsReloadBasis, disabled, ...props }, ref) => {
922+
cid, helpid, onChange, options, readonly = false, value, controlProps = {}, optionsLoaded, optionsReloadBasis, disabled, onError, ...props }, ref) => {
921923
const [[finalOptions, isLoading], setFinalOptions] = useState([[], true]);
922924
const theme = useTheme();
923925

@@ -953,6 +955,11 @@ export const InputSelect = forwardRef(({
953955
}
954956
setFinalOptions([res || [], false]);
955957
}
958+
})
959+
.catch((err)=>{
960+
let error_msg = err.response.data.errormsg;
961+
onError?.(error_msg);
962+
setFinalOptions([[], false]);
956963
});
957964
return () => umounted = true;
958965
}, [optionsReloadBasis]);
@@ -1052,14 +1059,20 @@ InputSelect.propTypes = {
10521059
onChange: PropTypes.func,
10531060
disabled: PropTypes.bool,
10541061
readonly: PropTypes.bool,
1062+
onError: PropTypes.func,
10551063
};
10561064

10571065

10581066
export function FormInputSelect({
10591067
hasError, required, className, label, helpMessage, testcid, labelTooltip, ...props }) {
1068+
const [selectError, setSelectError] = useState(null);
1069+
const handleSelectError = (errorMessage) => {
1070+
setSelectError(errorMessage);
1071+
};
1072+
10601073
return (
1061-
<FormInput required={required} label={label} error={hasError} className={className} helpMessage={helpMessage} testcid={testcid} labelTooltip={labelTooltip}>
1062-
<InputSelect ref={props.inputRef} {...props} />
1074+
<FormInput required={required} label={label} error={hasError} className={className} helpMessage={helpMessage} testcid={testcid} labelTooltip={labelTooltip} errorMessage={selectError}>
1075+
<InputSelect ref={props.inputRef} onError={handleSelectError} {...props} />
10631076
</FormInput>
10641077
);
10651078
}

0 commit comments

Comments
 (0)