Proposal: The gate keyword for conditional early returns

I recently looked at my code and realised that my core logic was diluted with error handling code. After calling a function, I want to be sure that whatever happens inside it worked as expected, so I always add the line “if (!res.success) return res” after each call. I know this can be avoided by throwing errors, but I want errors to be the last resort and only be thrown if a case occurred that was not handled correctly by the program.

So I thought it might be a good idea to have something like a special return keyword that checks the result and then only returns if the check fails .

I would like to suggest a kind of “mayReturn” keyword that has a built-in check and may return the current function's scope if a condition is met. It's difficult to come up with a name for this keyword, but it could be called “gate”. This would allow one to “gate” the resu lt.

When should the context be returned?

  1. undefined or null is returned.
  2. false is returned
  3. An object with a success key is returned, which is false.
  4. An object with an OK key is returned and it is false.

Examples:

Current:

let writeResult = await writeData(nodeId)
if (!writeResult.success) return writeResult

With the new "gate" keyword:

gate writeData(nodeId)

Or, in the case where the result is needed:
Current:

let configResult = await getConfig(nodeId)
if (!configResul t.success) return configResult
console.log(configResult)

With the new keyword:

let configResult = gate await writeData(nodeId)
console.log(configResult)

(It would be nice if one could just write gate, not gate and await, but I am not sure if this is possible.)

Let me know if this idea is worth pursuing. If someone wants to mentor the proposal process, feel free to reach out.

Thanks for reading this, and I hope that there is no obvious way to write this the same compact way out there t hat I am mis sing . If so, I a pologise in advance.

1 Like

Hi. I agree that error handling should be the last resort (stack trace is for debugging and is slower than “return {ok, data}”), but writing one “if” statement does not require extraordinary effort.

You could get a similar behavior with generators. Something along the lines of...

function isNonNullish(val) {
  return val != null
}

function gate(gen, cond = isNonNullish) {
  const iter = gen()
  let res = iter.next()
  while (!res.done) {
    if (cond(res.value)) {
      return res.value
    }
    res = iter.next(res.value)
  }
  return res.value
}

Then yields from a generator automatically apply the condition returning if that condition is true, otherwise resuming and continuing with more of the generator function, e.g.:

function writeData(success) {
  return { success }
}

function isSuccessful(data) {
  return data.success
}

const resultGoodData = gate(function* () {
  const writeResult = yield writeData(true)
  console.log("in gen:", writeResult)
  return -1
}, isSuccessful)

console.log(resultGoodData) // { success: true }


const resultBadData = gate(function* () {
  const writeResult = yield writeData(false)
  console.log("in gen:", writeResult)
  return -1
}, isSuccessful)
// in gen: { success: false }

console.log(resultBadData) // -1

Your AI wrote Go code, my friend. The standards committee will not fix it.