JavaScript error handling: can I throw an error inside a ternary operator?

Am I allowed to throw an error inside a ternary operator? Is this valid:

function foo(params) {

    var msg = (params.msg) ? params.msg : (throw "error");

    // do stuff if everything inside `params` is defined
}

What I'm trying to do is make sure all of the parameters needed, which are in a param object, are defined and throw an error if any one is not defined.

If this is just foolish, is there a better approach to doing this?

Answers:

Answer

You could do this:

function foo(params) {

    var msg = (params.msg) ? params.msg : (function(){throw "error"}());

    // do stuff if everything inside `params` is defined
}

I wouldn't really recommend it though, it makes for unreadable code.

This would also work (not that it's really much better):

function foo(params) {

    var msg = params.msg || (function(){throw "error"}());

    // do stuff if everything inside `params` is defined
}

Or for a cleaner approach, make a named function.

function _throw(m) { throw m; }
function foo(params) {

    var msg = params.msg || _throw("error");

    // do stuff if everything inside `params` is defined
}
Answer

No, it's absolutely not allowed. throw is a statement and it can't be part of an expression.

Unfortunately, I think that's the only way. You can use ifs without the braces:

if(!params.msg) throw new Error("msg is required!");

But there aren't any nice, easy workarounds that I know.

Answer

Here's a simple little trick that will throw from a ternary. I am simply calling a non-existent, impossible to ever exist, property on the undefined symbol. I have only checked chrome, and it can be caught and re-thrown as shown if you need it to have an appropriate error message but that is unnecessary bloat

try {
  var msg = (params.msg) ? params.msg : (void 0).throwError()
}
catch(e) {
  throw new Error('Params has no msg property')
}
Answer

You can throw an error like this inside a ternary operator,

function isPositive(a) {
    if(a > 0)
        return "YES";
    throw a == 0 ? Error("Zero Error") : Error("Negative Error");
}
Answer

This is a cleaner way that worked for me:

const msg = params.msg ? params.msg : ((function () { throw new Error('Message not found); }()));
Answer

To build upon @dagg's approach and the named function example; Here is the same but with default parameters with ES6:

function _throw(m) { throw new Error(m); }

function foo({ msg = _throw('msg parameter not defined') } = {}) {
  console.log(msg);
}

foo({ msg : 'party people!' }); // :D
foo({}); // throws!

Answer

Came across this while using fetch, here's the solution I offer for that particular case:

return fetch(url, request)
  .then(response => response.status >= 400 && response.status < 600 
    ? response.json().then(error => {throw new Error(error.message)})
    : response);

Note the (inline) block around throw which transforms the arrow-function body from a (return) expression to a statement.

Answer

building on @daggs answer a cleaner approach might be

function foo(params) {

   var err = function () {
    throw "error";
  };

    var msg = (params.msg) ? params.msg : err();

    // do stuff if everything inside `params` is defined
}
Answer

It is not possible and you shouldn't use an anonymous function for that. You'll break the error stack trace for nothing.

Tags

Recent Questions

Top Questions

Home Tags Terms of Service Privacy Policy DMCA Contact Us

©2020 All rights reserved.