JavaScript error handling: can I throw an error in

2020-02-26 18:51发布

问题:

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?

回答1:

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
}


回答2:

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.



回答3:

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')
}


回答4:

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");
}


回答5:

This is a cleaner way that worked for me:

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


回答6:

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!



回答7:

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.