Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Should I use console.error() or throw new Error()

Tags:

javascript

I've seen both:

throw new Error(error);

&

console.error(error);

E.G:

jQuery:

                if ( !w.document ) {
                    throw new Error( "jQuery requires a window with a document" );
                }

&
Vue.js:

      if (config.warnHandler) {
        config.warnHandler.call(null, msg, vm, trace);
      } else if (hasConsole && (!config.silent)) {
        console.error(("[Vue warn]: " + msg + trace));
      }

Both error handling ways seem reliable and used. But my question is:

Is there a difference between them? And if there is, when should I use which?

like image 897
Learn for Fun Avatar asked Feb 24 '20 21:02

Learn for Fun


3 Answers

The key difference: throwing halts the execution, while console.error does not.

Most of the time, it's better to throw an error.

That's a built-in way to signal that something failed and normal execution cannot continue unless the error is expected, caught and handled properly.

In the most platforms, an uncaught exception will be logged to the console as well to warn the developer about it, but caught exceptions won't be logged, since they are assumed to be handled by the code.

Using console.error can be good for cases where the error happened isn't fatal, but you'd like to warn the developer.

However, overusing this feature can easily cause other errors and harder-to-debug code. For example, consider this code:

const elem = document.querySelector('.elem')
if(!elem) 
  console.error('elem cannot be found!')
const returnValue = functionThatDoesSomethingWithElem(elem)
if(!returnValue.success) 
  console.error('Doing something with elem has failed!')
if(!returnValue.doSomethingElse()) 
  console.error('Doing something else with elem has failed!')

The above code will log three errors if there's no elem, but execution still continues, maybe causing even more errors.

By throwing an exception, this is avoidable:

const elem = document.querySelector('.elem')
if(!elem) 
  throw new Error('elem cannot be found!')
const returnValue = functionThatDoesSomethingWithElem(elem)
if(!returnValue.success) 
  throw new Error('Doing something with elem has failed!')
if(!returnValue.doSomethingElse()) 
  throw new Error('Doing something else with elem has failed!')

This will print only the first error message, and execution halts, unless you put it inside a try..catch structure, like:

try{
  const elem = document.querySelector('.elem')
  if(!elem) 
    throw new Error('elem cannot be found!')
  const returnValue = functionThatDoesSomethingWithElem(elem)
  if(!returnValue.success) 
    throw new Error('Doing something with elem has failed!')
  if(!returnValue.doSomethingElse()) 
    throw new Error('Doing something else with elem has failed!')
}catch(exception){
  console.error(exception)
  fallbackMethod()
}

There's another difference: thrown errors can be caught by the caller of your function, so it can programmatically handle them (causing the execution to continue, and the error isn't displayed). On the other hand, if you use console.error, the caller can not decide if an error is expected, causing to log the error even if it is normal, so the console can become messy (you can't decide what's a real error and what's not.

like image 88
FZs Avatar answered Sep 24 '22 19:09

FZs


Those two are completely different, let's see documentation of each one:

console.error:

Outputs an error message to the Web Console.

Throw:

throws a user-defined exception. Execution of the current function will stop (the statements after throw won't be executed), and control will be passed to the first catch block in the call stack. If no catch block exists among caller functions, the program will terminate.

So, as you can see, they work differently, you can use both in your code, so keep in mind that just a console.error will probably pass unseen by the user, only those with console open will see the message, while throw will be noted, since everything will stop.


Let's see some functional examples:
  • console.error

Note that the "custom" error will show on console, but code stills executing, you only see the error message because console is showing here in stackOverflow. To stop execution you would need a return right after the console.error

function changeString(currentString, append) {
  if (typeof append != 'string') {
    console.error("Cannot change string!");
  }

  //THIS PART BELOW WILL EXECUTE, even with error logged
  console.log(currentString + append);

}

changeString("I will show up even with error logged ", null)

  • Throw

Note that code stops execution when error is thrown and also the message of the error is different from the one that console.error shows.

function changeString(currentString, append){
  if (typeof append != 'string'){
    throw new Error("Cannot change string!");
  } 
  
  //THIS PART BELOW WONT EXECUTE
  console.log(currentString + append);
  
}

changeString("I wont show up in the console", null)

Here I added a try/catch, note the catch block being executed, this way I have control over the error and what should happen after the error being thrown, also, I mixed both: Throw and console.error

function changeString(currentString, append) {
  try {
    if (typeof append != 'string') {
      throw new Error("Cannot change string!");
    }
    
    console.log(currentString + append);
    
  } catch (er){
    console.error("I'm being logged from inside a catch block because an error was thrown");
    //DO WHATEVER YOU NEED TO FIX THE ERROR AND ALERT THE USER HERE
  }
}

changeString("I wont show up in the console", null)


Further read on official documentations:
Throw
console.error
like image 43
Calvin Nunes Avatar answered Sep 23 '22 19:09

Calvin Nunes


I would not consider them to be interchangeable. Console.error() simply logs your error to the console with special formatting.

When you actually throw an error you are essentially terminating execution unless you catch the error using a try catch block or some other form of error handling.

like image 38
Brady Ward Avatar answered Sep 24 '22 19:09

Brady Ward