Search code examples
throwgoogle-earth-engine

How to throw an error during a parameter check without if-statements in Google-Earth-Engine?


I am working on a new version of the bfast monitor algorithm in Google Earth Engine. See the code of the original algorithm on Github. The function bfastMonitor() takes user-defined parameters and applies some parameter checks before starting actual calculations. When the user-defined parameter settings are incompatible with the algorithm, an error should be raised.

During the parameter check, two types of if statements are made: statements that only check the parameter boundaries and raise an error at incompatible values, and statements that check and rewrite the contents of a parameter and raise an error at incompatible values. For the sake of the focus of this question, I will consider only the latter one.

Obviously, in a conventional coding paradigm, if-statements can be used to do this parameter check, however, using if-statements goes against the client-server model of GEE.

Consider the period parameter, which can only be 2,4,6,8, or 10. This parameter code used to index a list later in the code (line 459 on Github), where a period-value of 4 means that the list should be indexed at position 1, for instance.

Currently the implementation looks like this, using if-statements:

period = period||10

if (period == 2) {
   period  = 0;
} else if (period  == 4){
   period  = 1;
}else if (period  == 6){
   period  = 2;
}else if (period  == 8){
   period  = 3;
}else if (period  == 10){
   period  = 4;
}else {
  alert("Error: for period parameter, we only have 2, 4, 6, 8,10. Choose one of these values");
}

Later on, the period parameter is used a form like this (from Github):

var exampleList = ee.List([0.001, 0.002, 0.003, 0.004, 0.005]);
var exampleValue = exampleList[period]; 

The code could be rewritten easily to get rid of the if-statements, like this for instance:

var period = ee.Number(6);
var periodDict = ee.Dictionary({
  '2':0,
  '4':1,
  '6':2,
  '8':3,
  '10':4,
});
var exampleList = ee.List([0.001, 0.002, 0.003, 0.004, 0.005]);
var exampleValue = exampleList.get(periodDict.get(period.format()));

But then I don't know how to retain the opportunity to throw an error when the value for period is out of bounds.

How can I check the parameters of a function in Google Earth Engine and throw errors while avoiding if-statements?


Solution

  • There is nothing at all wrong with using a JavaScript if statement when it works. The advice you linked is about using ee.Algorithms.If which is unfortunately often inefficient — that's completely unrelated. The usual problem with a JavaScript if is when you're trying to use it on a server-side value that hasn't been computed yet.

    But in your case, it looks like you want to validate a user-provided parameter. if is a perfectly fine way to do this.

    I'll suggest one improvement: instead of using alert("error message");, use throw new Error:

      throw new Error("For period parameter, we only have 2, 4, 6, 8,10. Choose one of these values");
    

    This has two advantages:

    • It doesn't pop a dialog that the user must interact with before fixing the problem, but just results in an error message in the usual place, the Code Editor's Console.
    • It will stop the rest of the code from executing, which alert() doesn't.