3

Im looking for a way to do something like:

myVar = try {someFunction();} catch (e) {return undefined;} ?? defaultValue;

Which I know isn't correct but you get the idea. I just wondered if there was an elegant way to do this?

Peter Seliger
  • 11,747
  • 3
  • 28
  • 37
Gaetan L.
  • 649
  • 6
  • 20
  • 2
    There is none. You can use an IIFE if you must. There's also a (not yet official) [proposal](https://github.com/isiahmeadows/proposal-try-expression). – Bergi Aug 30 '20 at 20:53

3 Answers3

4

The best you can do currently is probably an IIFE:

myVar = (() => {
  try {
    return someFunction();
  } catch (e) {
  }
})() ?? defaultValue;
CertainPerformance
  • 356,069
  • 52
  • 309
  • 320
0

Implementing e.g. an afterThrowing method modifier could result in an expression as short and as close as to the OP's pseudo code ...

const value = try {someFunction();} catch (e) {return undefined;} ?? defaultValue;

... then would turn into something like ...

const value = (someFunction.afterThrowing(() => null)()) ?? defaultValue;

... implementation and example code as proof of concept ...

// myVar = try {someFunction();} catch (e) {return undefined;} ?? defaultValue;

function throwError() {
  throw (new Error('invocation failure'));
}
function getDate() {
  return Date.now();
}
const defaultValue = '... did throw.'

// expressions as short and as close as one can get
// to what has been ask for ...
//
console.log(
  (getDate.afterThrowing(() => null)()) ?? defaultValue
);
console.log(
  (throwError.afterThrowing(() => null)()) ?? defaultValue
);


// demonstrate capability of the after throwing handler ...
function afterThrowingHandler(error, args) {
  console.log(
    'afterThrowingHandler :: context, error, argsList :',
    this,
    error.toString(),
    Array.from(args)
  );
  return null; // according to the OP's use case.
}

console.log(
  (getDate.afterThrowing(afterThrowingHandler)()) ?? defaultValue
);

console.log(
  (throwError.afterThrowing(

    afterThrowingHandler,
    { biz: 'buzz' }

  )('foo', 'bar', 'baz')) ?? defaultValue
);
.as-console-wrapper { min-height: 100%!important; top: 0; }
<script>
  (function (Function) {

    const fctPrototype = Function.prototype;
    const FUNCTION_TYPE = (typeof Function);

    function isFunction(type) {
      return (
           (typeof type == FUNCTION_TYPE)
        && (typeof type.call == FUNCTION_TYPE)
        && (typeof type.apply == FUNCTION_TYPE)
      );
    }
    function getSanitizedTarget(target) {
      return ((target != null) && target) || null;
    }

    function afterThrowing/*Modifier*/(handler, target) {
      target = getSanitizedTarget(target);

      const proceed = this;
      return (

        isFunction(handler) &&
        isFunction(proceed) &&

        function () {
          const context = target || getSanitizedTarget(this);
          const args = arguments;

          let result;
          try {
            result = proceed.apply(context, args);

          } catch (exception) {

            result = handler.call(context, exception, args);
          }
          return result;
        }

      ) || proceed;
    }
    // afterThrowing.toString = () => 'afterThrowing() { [native code] }';

    Object.defineProperty(fctPrototype, 'afterThrowing', {
      configurable: true,
      writable: true,
      value: afterThrowing/*Modifier*/
    });

  }(Function));
</script>

I wouldn't mind if, at one day, JavaScript officially features ... Function.prototype[before|after|around|afterThrowing|afterFinally].

Peter Seliger
  • 11,747
  • 3
  • 28
  • 37
-1

Functional try catch

const tryF = (func) => {
  try {
    return func();
  } catch (e) {
    return null;
  }
};

Then to use

Const val = tryF(() => dosomething ())
sam
  • 1,005
  • 1
  • 11
  • 24