This is the 14th day of my participation in the August More Text Challenge

Errors are part of the programming process. There will be some errors in programming, and through these errors we can learn how to avoid such situations and how to do better next time.

In JavaScript, it doesn’t make sense to continue using the rest of the code statements when the code statements are tightly coupled and generate errors. Instead, we try to recover from our mistakes as gracefully as possible. The JavaScript interpreter checks the exception-handling code when such an error occurs, and if there is no exception handler, the program returns any function that caused the error.

This is repeated for each function on the call stack until an exception handler is found or the top function is reached, causing the program to terminate with an error, causing the program to crash.

Generally speaking, there are two ways to deal with it:

  • Throw an exception – If a problem that occurs at run time cannot be meaningfully handled, it is best to throw it
function openFile(fileName) {
  if(! exists(fileName)) {throw new Error('File not found' + fileName)
  }
  // ...
}
Copy the code
  • Catch exceptions – Thrown exceptions are caught and handled where it makes more sense at run time
try {
  openFile('.. /test.js')}catch(e) {
  // Handle raised expectations gracefully
}
Copy the code

Let’s look at these operations in more detail.

An exception is thrown

You might see something like ReferenceError: Specs is not defined. This represents an exception thrown by a throw statement.

grammar

throwThe « value »// Don't do that
if (somethingBadHappened) {
  throw 'Something bad happened'
}
Copy the code

There are no restrictions on the types of data that can be thrown as exceptions, but JavaScript has special built-in exception types. One of them is Error, as you saw in the previous example. These built-in exception types give us more detail than the exception messages.

Error

The Error type is used to represent a generic exception. This type of exception is most often used to implement user-defined exceptions. It has two built-in properties available.

  • message– Passed as a parameter toErrorConstructor contents. For example,new Error('This is an error message'). You can use themessageProperty access message.
const myError = new Error('Error!!! ')
​
console.log(myError.message) // Error!!!
Copy the code
  • stack– This property returns a history (call stack) of the file that caused the error. The top of the stack also includesmessage, followed by the actual stack, starting from the latest/quarantined error point to the most externally responsible file.
Error: Error!!!!!!!!! at <anonymous>:1:1
Copy the code

New Error(‘… ‘) does nothing until thrown, that is, throw new Error(‘ Error MSG ‘) creates an instance of Error in JavaScript and stops execution of the script unless you do something with the Error Error, such as catching it.

The catching

Now that we know what exceptions are and how to throw them, let’s talk about catching them to prevent them from ruining our program.

Try-catch-finally is the simplest way to handle exceptions.

try {
  // The code to run
} catch (e) {
  // The code to run when an exception occurs
}
  
[ / / is optional
  finally {
    // Code that always executes regardless of an exception}]Copy the code

In the try clause, we added code that might raise an exception. If an exception occurs, the catch clause is executed.

Sometimes, when code needs to be executed whether or not it raises an exception, we can use the optional block finally.

Even if a try or catch clause executes a return statement, the finally block executes. For example, the following function returns ‘Execute finally’ because the finally clause is the last thing to Execute.

function foo() {
  try {
    return true
  } finally {
    console.log('Execute finally')}}Copy the code

We use try-catches where we can’t check the correctness of the code in advance.

const user = '{"name": "D.O", "age": 18}'
try {
  // The code runs
  JSON.parse(params)
  // In the event of an error, the rest of the code will never run
  console.log(params)
} catch (err) {
  // The code that runs in the exception case
  console.log(err.message) // params is not defined
}
Copy the code

As shown above, it is not possible to examine json.parse to get a Stringify object or string before executing the code.

Note: You can catch program-generated exceptions and runtime exceptions, but you cannot catch JavaScript syntax errors.

Try-catch-finally can only catch synchronization errors. If we try to use it for asynchronous code, the try-catch-finally may be executed before the asynchronous code completes its execution.

How do I handle exceptions in asynchronous code blocks

The callback function

Using the callback function (not recommended), we usually receive two arguments like this:

async function(code, (err, result) => {
  if (err) return console.error(err)
  console.log(result)
})
Copy the code

We can see that there are two parameters: err and result. If there is an error, the err parameter will be equal to the error, which we can throw for exception handling.

It’s important to return something in an if (ERR) block or wrap other instructions in an else block. Otherwise, you may encounter another error. For example, result may not be defined when you try to access result.data.

Promises

Using promises’ then or Catch, we can handle errors by passing error handlers to then methods or using catch clauses.

promise.then(onFulfilled, onRejected)
Copy the code

You can also add an error handler using.catch(onRejected) instead of.then(null, onRejected), which works in the same way.

Let’s look at an example of. Catch rejecting a Promise.

Promise.resolve('1')
  .then(res= > {
    console.log(res) / / 1
    throw new Error('go wrong') // Throw an exception
})
.then(res= > {
  console.log(res) // Will not be executed
})
.catch(err= > { 
  console.error(err) // Catch and handle exceptions -- > Error: go wrong
})
Copy the code

useasync/awaittry-catch

With async/await and try-catch-finally, handling exceptions is a breeze.

async function func() {
  try {
    await nonExistentFunction()
  } catch (err) {
    console.error(err) // ReferenceError: nonExistentFunction is not defined }}Copy the code

How do I handle uncaught exceptions

Now that we have a good understanding of how to perform exception handling in both synchronous and asynchronous blocks of code, let’s answer the final open question of this article: How do we handle uncaught exceptions?

In the browser

We can use the window.onerror() method to handle uncaught exceptions. This method raises an error event on the Window object whenever an error occurs at runtime.

Another useful use of onError () is to trigger actions when loading data such as images or videos in a site fails. For example, provide a picture of a loading error, or display a message.

<img src="logo.png" onerror="alert('Error loading picture.')" />
Copy the code

In the Node. Js

Process objects derived from the EventEmitter module can subscribe to the event uncaughtException.

process.on('uncaughtException'.() = > {})`
Copy the code

We can pass a callback to handle the exception. If we try to catch this uncaught exception, the process will not terminate, so we must do it manually.

UncaughtException applies only to synchronized code. For asynchronous code, there is another event called unhandledRejection.

process.on('unhandledRejection'.() = > {})
Copy the code

Never try to implement a catch-all handler for basic Error types. This confuses everything that happens and harms the maintainability and extensibility of the code.

The key points

  • throwStatement is used to generate user-defined exceptions. At runtime, whenthrowWhen a statement is encountered, execution of the current function stops and control is passed tocatchThe first clause in the call stack. If there is nocatchClause, the program will terminate
  • JavaScript has a few built-in exception types, most notablyError, it returnsErrorTwo important properties in:stackmessage.
  • tryThe clause will contain code that might generate an exception,catchThe clause is executed when an exception occurs.
  • For asynchronous code, this is best usedasync/awaitCooperate withtry-catchStatements.
  • Unhandled exceptions can be caught, which prevents the application from crashing.

Don’t bother; exception handling can help you make your code more maintainable, extendable, and readable.