Try/catch oneliner available?
Asked Answered
H

6

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.

Heres answered 26/2, 2011 at 11:15 Comment(0)
P
15

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;
} 
Proliferation answered 26/2, 2011 at 11:48 Comment(1)
here's an upvote for "i'll never use it"Aggappera
D
10

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');
Dwell answered 16/10, 2019 at 18:58 Comment(1)
I love this solution, because it helped me understand why try/catch has always bothered me. It doesn't match the functional style that I use for everything else! I have to sort on mentally shift gear when reading a try catch statement, because it doesn't flow the same way as the rest of the code.Blindheim
R
9

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.

Ragan answered 26/2, 2011 at 11:18 Comment(4)
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.Heres
@pimvdb: if is a statement and ?: is an expression. They are different although they can be used in a similar manner.Mazdaism
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.Heres
"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.Gesture
D
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.

Dunnage answered 26/2, 2011 at 11:21 Comment(5)
You can get it down to one line... try { doSomething(); } catch (e) { handleError(); }Girvin
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.Heres
@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.Ragan
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.Girvin
I definitely prefer the "two-liner" method. It's clean and still easy to read.Solar
K
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".

Kathaleenkatharevusa answered 9/7, 2020 at 0:11 Comment(0)
H
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);
Heisenberg answered 6/2, 2023 at 15:6 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.