Exceptions: The Party Crashers of Your Code (And How to Handle Them)

Exceptions: The Party Crashers of Your Code (And How to Handle Them)

Introduction

We all prefer things to go smoothly without any interruptions or obstacles, whether it's in our personal lives or in our work as coders. However, unexpected events and uncertainties can disrupt even the best-laid plans. For example, imagine you're trying to access a file online, but your internet connection suddenly goes down. Or you're talking to your significant other, and your phone unexpectedly shuts off.

Exception

The exception is a condition that interrupts the normal code execution - MDN.

You have created a program that retrieves data from a server and presents the output on the screen, as shown in the animation above. However, an unexpected error occurred, causing the program to crash and leaving the user with a strange page on their screen.

An exception can occur when there is an error or unexpected condition that prevents the code from executing as expected, common reasons could be among the following: Syntax Error, Runtime Error, Logical Error, and Network Error. And when the code faces any of the above conditions it just halts the program execution and throws an error.

Oops! the system crashes and the user has no idea about why it happened, Rather than simply stopping the entire application, a better approach is to implement exception handling. This involves identifying and addressing specific issues as they arise, rather than allowing them to bring down the entire system. It improves user experience and ensures the reliability of the application.

Exception Handling

The above code snippet prints the message to the user by getting the user's name and age. However, it has a flaw in that if the user fails to provide their age or name, the program displays "undefined" which can be confusing for the user. Additionally, the code does not validate whether the input for age is a number, which can result in a bad user experience. I've just provided a simple example but in real-world scenarios, there could be tons of things out of which exception occurs.

Throw Statement:

In the code snippet provided, a ReferenceError is being thrown because a variable that has not been defined is being accessed. Although it may seem unnecessary to include this example, it serves to illustrate that even the error we get from JavaScript is internally raised using the throw keyword.

How to raise customized exceptions?

To demonstrate the creation of a custom exception, let's consider the previous example where we printed a message to the user. In this updated version, I've added an extra check to ensure that the user's input is a number. If the user enters a non-numeric value, it'll throw a custom exception.

Ahh! what's that? How it's happening?

If you're perplexed or thinking about the behavior it's not strange. At first, it might seem bewildering. To make things clear let me explain the internal flow of throw statement.

  1. The diagram explains a JavaScript engine, which is responsible for executing JavaScript code.

  2. The engine has started to execute the code.

  3. At some point in the execution of the code, a throw statement is encountered.

  4. When a throw statement is encountered, the engine creates an error object and attaches it to the current execution context an error object generally have a name, message, stack, etc.

  5. The engine then searches the call stack to find a matching try-catch block that can handle the error.

  6. If a try-catch block is found, the error is caught and control is transferred to the corresponding catch block.

  7. The catch block handles the error by executing the logic written in the code.

  8. Once the error is handled, the engine resumes execution from the point where the try-catch block was located.

Note: In step 6 If no try-catch block is found in the call stack, the error is considered unhandled and may cause the program to terminate.

TRY... CATCH

When an exception occurs during the execution of a program, it can cause the program to stop abruptly. This can be a problem if we want the program to continue running even if an error occurs. In such cases, we can use the try-catch construct to handle exceptions in a more controlled manner. The try block contains the code that we want to execute, and the catch block contains the code that we want to run if an exception occurs. If an exception occurs in the try block, the program jumps to the catch block to handle the exception.

Using try-catch can be compared to a real-life scenario where a student is preparing for an exam. The student tries hard to do well in the exam, but if they fail, their parent's console and support them. Similarly, in a program, we can try to execute code and handle any exceptions that occur, without causing the program to crash.

Let's take a couple of examples:

This code snippet is identical to the previous one, except that we're invoking another function, "printAnotherMessage," after "printMessageToUser." However, there is no "try...catch" block. When a program encounters a "throw" statement, it immediately halts execution and does not proceed to the next function.

In this updated version of the code, I've incorporated a "try...catch" block within the "printMessageToUser" function. If the program encounters a "throw" statement, it executes the code within the "catch" block, then resumes execution of the program and runs the "printAnotherMessage" function.

Conclusion

Try and Catch is useful for preventing unexpected crashes in a program and providing more meaningful feedback to users when something goes wrong and in general an Application should handle the exception. By handling exceptions in a controlled way, programmers can ensure that their code is more robust and reliable.