From 0f511eb3f32676603ade85734bac1880e1e007ca Mon Sep 17 00:00:00 2001 From: Matthias Mohr Date: Tue, 23 Jan 2024 15:06:43 +0100 Subject: [PATCH] Return error if bands don't exist #31 --- src/processes/aggregate_temporal_frequency.js | 13 +-- src/processes/array_element.js | 6 +- src/processes/filter_bands.js | 6 +- src/processes/first.js | 3 +- src/processes/last.js | 3 +- src/processes/rename_labels.js | 13 +-- src/processgraph/commons.js | 91 +++++-------------- src/processgraph/context.js | 1 + src/processgraph/node.js | 15 ++- 9 files changed, 44 insertions(+), 107 deletions(-) diff --git a/src/processes/aggregate_temporal_frequency.js b/src/processes/aggregate_temporal_frequency.js index 7b82699..76c6fe6 100644 --- a/src/processes/aggregate_temporal_frequency.js +++ b/src/processes/aggregate_temporal_frequency.js @@ -1,28 +1,19 @@ import GeeProcess from '../processgraph/process.js'; import Commons from '../processgraph/commons.js'; -import Errors from '../utils/errors.js'; export default class aggregate_temporal_frequency extends GeeProcess { reduce(node, imageCollection) { const callback = node.getCallback('reducer'); if (callback.getNodeCount() !== 1) { - throw new Errors.ProcessArgumentInvalid({ - process: this.id, - argument: 'reducer', - reason: "No complex reducer supported at the moment" - }); + throw node.invalidArgument('reducer', 'No complex reducer supported at the moment'); } else { // This is a simple reducer with just one node const childNode = callback.getResultNode(); const process = callback.getProcess(childNode); if (typeof process.geeReducer !== 'function') { - throw new Errors.ProcessArgumentInvalid({ - process: this.id, - argument: 'reducer', - reason: 'The specified reducer is invalid.' - }); + throw node.invalidArgument('reducer', 'The specified reducer is invalid.'); } node.debug("Bypassing node " + childNode.id + "; Executing as native GEE reducer instead."); const reducerFunc = process.geeReducer(node); diff --git a/src/processes/array_element.js b/src/processes/array_element.js index 0bb229b..9f49cb9 100644 --- a/src/processes/array_element.js +++ b/src/processes/array_element.js @@ -30,11 +30,7 @@ export default class array_element extends GeeProcess { else { // ToDo processes: only bands is currently supported if (dimension.type !== "bands") { - throw new Errors.ProcessArgumentInvalid({ - process: this.id, - argument: 'dimension', - reason: 'Only dimension "bands" is currently supported.' - }); + throw node.invalidArgument('dimension', 'Only dimension "bands" is currently supported.'); } else { index = labels.indexOf(label); diff --git a/src/processes/filter_bands.js b/src/processes/filter_bands.js index 9cfae92..4efb576 100644 --- a/src/processes/filter_bands.js +++ b/src/processes/filter_bands.js @@ -3,14 +3,10 @@ import Commons from '../processgraph/commons.js'; export default class filter_bands extends GeeProcess { - process(data, bands, node) { - return Commons.filterBands(data, bands, node); - } - executeSync(node) { const dc = node.getDataCube('data'); const bands = node.getArgument('bands'); - return this.process(dc, bands, node); + return Commons.filterBands(dc, bands, node); } } diff --git a/src/processes/first.js b/src/processes/first.js index 08fc176..25470f3 100644 --- a/src/processes/first.js +++ b/src/processes/first.js @@ -1,5 +1,4 @@ import GeeProcess from '../processgraph/process.js'; -import Errors from '../utils/errors.js'; export default class first extends GeeProcess { @@ -21,7 +20,7 @@ export default class first extends GeeProcess { return data.first(); } else { - throw new Errors.ProcessArgumentInvalid(); + throw node.invalidArgument('data', 'Unsupported datatype'); } } diff --git a/src/processes/last.js b/src/processes/last.js index be302d4..76b0809 100644 --- a/src/processes/last.js +++ b/src/processes/last.js @@ -1,5 +1,4 @@ import GeeProcess from '../processgraph/process.js'; -import Errors from '../utils/errors.js'; export default class last extends GeeProcess { @@ -23,7 +22,7 @@ export default class last extends GeeProcess { return data.toList(data.size()).get(-1); } else { - throw new Errors.ProcessArgumentInvalid(); + throw node.invalidArgument('data', 'Unsupported datatype'); } } diff --git a/src/processes/rename_labels.js b/src/processes/rename_labels.js index 8b9b228..dd9a285 100644 --- a/src/processes/rename_labels.js +++ b/src/processes/rename_labels.js @@ -1,5 +1,4 @@ import GeeProcess from '../processgraph/process.js'; -import Errors from '../utils/errors.js'; export default class rename_labels extends GeeProcess { @@ -17,21 +16,13 @@ export default class rename_labels extends GeeProcess { const source = node.getArgument("source"); if (!dc.hasDimension(dimensionName)) { - throw new Errors.ProcessArgumentInvalid({ - process: this.id, - argument: 'dimension', - reason: 'Dimension "' + dimensionName + '" does not exist.' - }); + throw node.invalidArgument('dimension', `Dimension '${dimensionName}' does not exist.`); } // ToDo processes: only bands is currently supported const dimension = dc.getDimension(dimensionName); if (dimension.type !== "bands") { - throw new Errors.ProcessArgumentInvalid({ - process: this.id, - argument: 'dimension', - reason: 'Only dimension "bands" is currently supported.' - }); + throw node.invalidArgument('dimension', `Only dimension "bands" is currently supported.`); } // ToDo processes: Number values for the labels arguments causes problems dc.renameLabels(dimension, target, source); diff --git a/src/processgraph/commons.js b/src/processgraph/commons.js index 34ad196..9d37aae 100644 --- a/src/processgraph/commons.js +++ b/src/processgraph/commons.js @@ -12,11 +12,7 @@ export default class Commons { const dimensionName = node.getArgument(dimensionArgName); const dimension = dc.getDimension(dimensionName); if (!allowedDimensionTypes.includes(dimension.type)) { - throw new Errors.ProcessArgumentInvalid({ - process: process_id, - argument: dimensionArgName, - reason: 'Reducing dimension types other than ' + allowedDimensionTypes.join(' or ') + ' is currently not supported.' - }); + throw node.invalidArgument(dimensionArgName, `Reducing dimension types other than ${allowedDimensionTypes.join(' or ')} is currently not supported.`); } const callback = node.getCallback(reducerArgName); @@ -25,11 +21,7 @@ export default class Commons { const childNode = callback.getResultNode(); const process = callback.getProcess(childNode); if (typeof process.geeReducer !== 'function') { - throw new Errors.ProcessArgumentInvalid({ - process: process_id, - argument: reducerArgName, - reason: 'The specified ' + reducerArgName + ' is invalid.' - }); + throw node.invalidArgument(reducerArgName, 'The specified reducer is invalid.'); } node.debug("Bypassing node " + childNode.id + "; Executing as native GEE reducer instead."); dc = Commons.reduceSimple(dc, process.geeReducer(node)); @@ -108,18 +100,10 @@ export default class Commons { const arg1 = node.getArgument(arg1Name); const arg2 = node.getArgument(arg2Name); if (typeof arg1 === 'undefined') { - throw new Errors.ProcessArgumentInvalid({ - process: node.process_id, - argument: arg1Name, - reason: "Argument is undefined." - }); + throw node.argumentInvalid(arg1Name, "Argument is undefined."); } if (typeof arg2 === 'undefined') { - throw new Errors.ProcessArgumentInvalid({ - process: node.process_id, - argument: arg2Name, - reason: "Argument is undefined." - }); + throw node.argumentInvalid(arg2Name, "Argument is undefined."); } return this._reduceBinary(node, imgReducer, jsReducer, arg1, arg2, arg1Name + "/" + arg2Name); @@ -128,11 +112,7 @@ export default class Commons { static reduceInCallback(node, imgReducer, jsReducer, dataArg = "data") { const list = node.getArgument(dataArg); if (!Array.isArray(list) || list.length <= 1) { - throw new Errors.ProcessArgumentInvalid({ - process: node.process_id, - argument: dataArg, - reason: "Not enough elements." - }); + throw node.invalidArgument(dataArg, "Argument must be an array with at least two elements."); } let result; @@ -178,11 +158,7 @@ export default class Commons { result = dataCubeB.imageCollection(ic => ic.map(imgB => imgReducer(imgA, imgB))); } else { - throw new Errors.ProcessArgumentInvalid({ - process: node.process_id, - argument: dataArg, - reason: "Reducing number with unknown type not supported" - }); + throw node.invalidArgument(dataArg, "Reducing number with unknown type not supported"); } } else if (dataCubeA.isImageCollection()) { @@ -202,11 +178,7 @@ export default class Commons { }); } else { - throw new Errors.ProcessArgumentInvalid({ - process: node.process_id, - argument: dataArg, - reason: "Reducing image collection with unknown type not supported" - }); + throw node.invalidArgument(dataArg, "Reducing image collection with unknown type not supported"); } } else if (dataCubeA.isImage()) { @@ -218,19 +190,11 @@ export default class Commons { result = dataCubeB.imageCollection(ic => ic.map(imgB => imgReducer(dataCubeA.image(), imgB))); } else { - throw new Errors.ProcessArgumentInvalid({ - process: node.process_id, - argument: dataArg, - reason: "Reducing image with unknown type not supported" - }); + throw node.invalidArgument(dataArg, "Reducing image with unknown type not supported"); } } else { - throw new Errors.ProcessArgumentInvalid({ - process: node.process_id, - argument: dataArg, - reason: "Reducing an unknown type is not supported" - }); + throw node.invalidArgument(dataArg, "Reducing unknown type not supported"); } return result; } @@ -269,31 +233,30 @@ export default class Commons { dc.setSpatialExtent(bbox); return Commons.restrictToSpatialExtent(node, dc); } catch (e) { - throw new Errors.ProcessArgumentInvalid({ - process: process_id, - argument: paramName, - reason: e.message - }); + throw node.invalidArgument(paramName, e.message); } } - static filterBands(dc, bands, node) { + static filterBands(dc, bands, node, parameterName = 'bands') { const dc_bands = dc.getBands(); const col_id = dc.getCollectionId(); const col_meta = node.getContext().getCollection(col_id); + const eo_bands = Array.isArray(col_meta.summaries["eo:bands"]) ? col_meta.summaries["eo:bands"] : []; + const band_list = []; - for(const b of bands) { - if (dc_bands.indexOf(b) > -1) { - band_list.push(b) + for(const name of bands) { + if (dc_bands.indexOf(name) > -1) { + band_list.push(name); + continue; } - else { - for (const eob of col_meta.summaries["eo:bands"]){ - if (b === eob["common_name"]) { - band_list.push(eob["name"]); - break; - } - } + + const match = eo_bands.find(eob => name === eob.common_name && typeof eob.name === 'string'); + if (match) { + band_list.push(match.name); + continue; } + + throw node.invalidArgument(parameterName, `Band with name or common name '${name}' not found in data cube.`); } dc.imageCollection(ic => ic.select(band_list)); dc.dimBands().setValues(band_list); @@ -308,11 +271,7 @@ export default class Commons { dc.imageCollection(ic => ic.map(img => img.clip(geom))); return dc; } catch (e) { - throw new Errors.ProcessArgumentInvalid({ - process: process_id, - argument: paramName, - reason: e.message - }); + throw node.invalidArgument(paramName, e.message); } } diff --git a/src/processgraph/context.js b/src/processgraph/context.js index e913d25..456a91c 100644 --- a/src/processgraph/context.js +++ b/src/processgraph/context.js @@ -118,6 +118,7 @@ export default class ProcessingContext { throw new Errors.ProcessArgumentInvalid({ argument: "options", process: "save_result", + namespace: "backend", reason: "The output band definitions are not properly given." }); } diff --git a/src/processgraph/node.js b/src/processgraph/node.js index 02cee9d..6e0ed83 100644 --- a/src/processgraph/node.js +++ b/src/processgraph/node.js @@ -62,13 +62,18 @@ export default class GeeProcessGraphNode extends ProcessGraphNode { getCallback(name) { const callback = this.getArgument(name); if (!(callback instanceof ProcessGraph)) { - throw new Errors.ProcessArgumentInvalid({ - process: this.process_id, - argument: 'process', - reason: 'No process specified.' - }); + throw this.invalidArgument('process', 'No process specified.'); } return callback; } + invalidArgument(argument, reason) { + return new Errors.ProcessArgumentInvalid({ + process: this.process_id, + namespace: this.namespace, + argument, + reason + }); + } + }