37

Just as you can convert the following:

var t;
if(foo == "bar") {
    t = "a";
} else {
    t = "b";
}

into:

t = foo == "bar" ? "a" : "b";

, I was wondering if there is a shorthand / oneline way to convert this:

var t;
try {
    t = someFunc();
} catch(e) {
    t = somethingElse;
}

Is there a method of doing this in a shorthand way, preferably an oneliner? I could, of course, just remove the newlines, but I rather mean something like the ? : thing for if.

Thanks.

pimvdb
  • 151,816
  • 78
  • 307
  • 352

6 Answers6

14

You could use the following function and then use that to oneline your try/catch. It's use would be limited and makes the code harder to maintain so i'll never use it.

var v = tc(MyTryFunc, MyCatchFunc);

tc(function() { alert('try'); }, function(e) { alert('catch'); });


/// try/catch 
function tc(tryFunc, catchFunc) {
     var val;
     try {
        val = tryFunc();
     }
     catch (e) {
         val = catchFunc(e);
     }
     return val;
} 
rene
  • 41,474
  • 78
  • 114
  • 152
10

No, there isn't a "one-liner" version of try-catch besides simply removing all the newlines.

Why would you want to? Vertical space doesn't cost you anything.

And even if you'll settle for removing all the newlines, this, in my opinion, is harder to read:

try{t = someFunc();}catch(e){t = somethingElse;}

than this:

try {
    t = someFunc();
} catch(e) {
    t = somethingElse;
}

What you have is perfectly fine. Readable code should be a priority. Even if it means more typing.

In silico
  • 51,091
  • 10
  • 150
  • 143
  • Ok, then it's just a pity. I was just wondering, because for a simple `if` block, I prefer a `? :` line, as it's clearer and less typing. So perhaps there was something similar available for `try catch`, but apparently there isn't. – pimvdb Feb 26 '11 at 11:21
  • 1
    @pimvdb: `if` is a statement and `?:` is an expression. They are different although they can be used in a similar manner. – Gumbo Feb 26 '11 at 11:26
  • I understand that readability is more important, but if there *was* a shorthand `try catch` expression, I think that would be more readable. But I'll just forget about it as it doesn't exist. @Gumbo: I wasn't aware of that as it just behaves similarly. Thank you. – pimvdb Feb 26 '11 at 11:29
  • 8
    "Vertical space doesn't cost you anything": not true, visual noise, scrolling, time for humans to parse are real costs, especially when they are initially looking for the main execution path, not error handling. There is a good reason why most IDEs fold up imports for Java. – Adrian Baker Jan 07 '18 at 07:06
9

There is one liner available as npm package try-catch. You can use it this way:

const tryCatch = require('try-catch');
const {parse} = JSON;

const [error, result] = tryCatch(parse, 'hello');

There is similar approach for async-await try-to-catch:

const {readFile} = require('fs').promises;

read('./package.json').then(console.log);

async function read(path) {
    const [error, data] = await tryToCatch(readFile, path, 'utf8');

    return data || error.message;
}

All this wrappers do is wrap one function with try-catch block and uses destructuring to get result.

Also there is an idea to use something similar to Go style error handling:

// this is not real syntax
const [error, result] = try parse('hello');
coderaiser
  • 749
  • 5
  • 15
7

You can get it down to two lines.

try { doSomething(); }
catch (e) { handleError(); }

Or, in your specific example, 3 lines.

var t;
try { t = doSomething(); }
catch (e) { t = doSomethingElse(); }

Either way, if your code allows for it, a two liner is much more concise, IMO, than the typical try/catch block.

Chris
  • 27,596
  • 25
  • 124
  • 225
  • 2
    You can get it down to one line... `try { doSomething(); } catch (e) { handleError(); }` – Leigh Feb 26 '11 at 11:23
  • That seems the most cleanest solution, thanks. @Leigh: That again is less clean in my honest opinion. Actually, I was looking for something like `var t = doSomething() : handleError()`, which would mean what you use. – pimvdb Feb 26 '11 at 11:24
  • @Leigh: The OP knows that you can make it a one-liner by removing the newlines. The OP was asking if there was a built-in language construct that was shorthand for `try..catch`. – In silico Feb 26 '11 at 11:24
  • 2
    I'm very much aware it's less clean. I guess my point was: What's the point in saying "you can get it down to two lines" which is just as obvious as saying you can get it down to one. – Leigh Feb 26 '11 at 12:03
  • I definitely prefer the "two-liner" method. It's clean and still easy to read. – dsanchez Oct 21 '20 at 06:50
2

While this doesn't help with your question about shorthand, it could help if you are seeking to get a try-catch working in an inline context which expects an expression (as distinct from statements, as try-catch uses).

You can achieve this by wrapping the try-catch into an IIFE, which, though an expression, lets you add statements within it that are immediately executed:

var t, somethingElse;
var failingCondition = false;
var result = failingCondition || (function () {
    try {
        t = someFunc();
    } catch(e) {
        t = somethingElse;
    }
})();

The above is probably of little use but you could conditionally return values also:

var t, somethingElse;
var failingCondition = false;
var result = failingCondition || (function () {
    try {
        t = someFunc();
        return 'someFunc';
    } catch(e) {
        t = somethingElse;
        return 'somethingElse';
    }
})();

Since someFunc() fails here (in our case, since it is not defined), result will equal "somethingElse".

Brett Zamir
  • 14,034
  • 6
  • 54
  • 77
1

Here it is using only js:

const result = (()=>{ try{ return fn(); } catch(e) { return "other"; } })();

const badFn = ()=>{ return JSON.parse("broken json"); }
const result = (()=>{ try{ return badFn(); } catch(e) { return "other"; } })();
console.log(result);
enesn
  • 2,063
  • 1
  • 10
  • 13