1

Is it a good practice to throw an error if a function is invoked and missing a parameter that is necessary for the invoked function to be executed properly?

For example (in JavaScript):

var sayHi = function(name) {
  console.log(name + ' says hi!');
}

vs.

var sayHi = function(name) {
  if(!name) { throw new Error('param is missing'); }
  console.log(name + ' says hi!');
}  

Is there a strong opinion about wether the second example is a good coding practice or if it only adds unnecessary bloating that might lead to frequently unnecessary errors being thrown in a more complex program spanning tens or even hundred of files?

fredmaggiowski
  • 2,232
  • 3
  • 25
  • 44
  • This is all up to opinion. I tend not to include such checks as they slow down my code leaving the onus on the programmer to call their functions correctly. Alternatively, you could use a statically typed language such as [TypeScript](http://www.typescriptlang.org/) which ensures that functions are always called with the right number of arguments. – Mike Cluck Apr 12 '16 at 17:27
  • @raiti13 if some of the answers helped you please accept it to provide help to future users :) – fredmaggiowski Apr 21 '16 at 07:34

3 Answers3

4

You can achieve that with es6 passing a function that immediately throws an Error as default value

const err = msg => { throw Error( msg ) }

const sayHi = function(name = err('Name is undefined')) {
  console.log(name + ' says hi!');
}

This has slightly better performance than having the if statement inside the body of the function and improves the readability. Another think that you can do is to build a decorator that does the same. Something like:

@required( 'name')
const sayHi = function(name = err('Name is undefined')) {
  console.log(name + ' says hi!');
}

As you mention in your question Is there a strong opinion, the answer could only be mostly opinionated, so in my opinion you should always have an error handling strategy. Either in function lever or in application level. Its very unlikely in my opinion that error-handling will be your performance bottleneck.

Avraam Mavridis
  • 8,698
  • 19
  • 79
  • 133
  • This doesn't answer the question. This is just a convenient way of doing what OP is already doing. They're asking if they *should* be throwing an error when an argument isn't given. – Mike Cluck Apr 12 '16 at 17:28
  • 1
    @MikeC having it as default parameter instead of checking inside the body of the function improves the performance and makes the code more readable... So I think is not so unrelated with the question. Anyway, thx for the downvote. – Avraam Mavridis Apr 12 '16 at 17:30
  • Except that it doesn't. That check is still being performed somewhere and if you're [compiling your code down to ES5](https://babeljs.io/repl/#?evaluate=true&presets=es2015%2Creact%2Cstage-2&experimental=true&loose=false&spec=false&code=const%20err%20%3D%20msg%20%3D%3E%20%7B%20throw%20Error(%20msg%20)%20%7D%0D%0A%0D%0Aconst%20sayHi%20%3D%20function(name%20%3D%20err('Name%20is%20undefined'))%20%7B%0D%0A%20%20console.log(name%20%2B%20'%20says%20hi!')%3B%0D%0A%7D) then it is transformed directly into a check similar to what OP posted. – Mike Cluck Apr 12 '16 at 17:35
  • Current ES6 implementations, especially for default parameters, are not very efficient. Show me proof that this is faster in current ES6 environments. Furthermore this, again, doesn't address the actual question which is "what is the best practice for this situation?" – Mike Cluck Apr 12 '16 at 17:36
  • @MikeC well, yeah, I agree, if you transpile your code to ES5 of course there is no difference. But if you dont its native check vs js check. – Avraam Mavridis Apr 12 '16 at 17:37
3

First thing first:

It's really up to you to decide wether you should or shouldn't throw exception rather than return an error code (or null, or whatever).

As far as I know there're no great issues in throwing exceptions rather than returning errors as far as you handle them properly.

This leads to the following question:

When is correct to throw an exception (or Error in JS)?

The question is pretty tricky, and here should be flagged and closed as "primarily opinion based" since this is up to personal opinion.. well, maybe..

A similar question (well.. this exact question) has already been asked and replied here and I find myself agreeing with the accepted answer, summed up in this comment:

Exactly! An exception is thrown when and only when function preconditions (assumptions about arguments) are broken! – @Lightman

In your situation, if the assumptions of your function (your expected parameter) are violated: YES, throw an exception, since JS doesn't provide any syntax construct to set a function parameter as required.


With ES6 you can use default parameters to force something like the behaviour you want:
function required() {
  throw new Error('Missing parameter');
}

function foo(aRequiredParameter = required()) {

  // Use your required parameter
  console.log("Hello " + aRequiredParameter);
}

// Hence:
foo("World") // OK
foo()        // -> Throws exception

Example taken from here, while here you can find more examples about this feature.

This is achievable because, when aRequiredParameter is not passed it's default value will be assigned (in this case invoked) and hence the exception/error will be threw.

fredmaggiowski
  • 2,232
  • 3
  • 25
  • 44
0

It depends. You should almost always have some kind of error handling, but what type of handling depends on the situation.

Sometimes just throwing an error is fine, other times you might want to do something if you have an error.

You could use something like a try/catch, or, in this case just check for undefined and do something with that.