Close Menu
    DevStackTipsDevStackTips
    • Home
    • News & Updates
      1. Tech & Work
      2. View All

      Error’d: Pickup Sticklers

      September 27, 2025

      From Prompt To Partner: Designing Your Custom AI Assistant

      September 27, 2025

      Microsoft unveils reimagined Marketplace for cloud solutions, AI apps, and more

      September 27, 2025

      Design Dialects: Breaking the Rules, Not the System

      September 27, 2025

      Building personal apps with open source and AI

      September 12, 2025

      What Can We Actually Do With corner-shape?

      September 12, 2025

      Craft, Clarity, and Care: The Story and Work of Mengchu Yao

      September 12, 2025

      Cailabs secures €57M to accelerate growth and industrial scale-up

      September 12, 2025
    • Development
      1. Algorithms & Data Structures
      2. Artificial Intelligence
      3. Back-End Development
      4. Databases
      5. Front-End Development
      6. Libraries & Frameworks
      7. Machine Learning
      8. Security
      9. Software Engineering
      10. Tools & IDEs
      11. Web Design
      12. Web Development
      13. Web Security
      14. Programming Languages
        • PHP
        • JavaScript
      Featured

      Using phpinfo() to Debug Common and Not-so-Common PHP Errors and Warnings

      September 28, 2025
      Recent

      Using phpinfo() to Debug Common and Not-so-Common PHP Errors and Warnings

      September 28, 2025

      Mastering PHP File Uploads: A Guide to php.ini Settings and Code Examples

      September 28, 2025

      The first browser with JavaScript landed 30 years ago

      September 27, 2025
    • Operating Systems
      1. Windows
      2. Linux
      3. macOS
      Featured
      Recent
    • Learning Resources
      • Books
      • Cheatsheets
      • Tutorials & Guides
    Home»Development»The JavaScript Error Handling Handbook

    The JavaScript Error Handling Handbook

    July 11, 2025

    Errors and exceptions are inevitable in application development. As programmers, it is our responsibility to handle these errors gracefully so that the user experience of the application is not compromised. Handling errors correctly also helps programmers debug and understand what caused them so they can deal with them.

    JavaScript has been a popular programming language for over three decades. We build web, mobile, PWA, and server-side applications using JavaScript and various popular JavaScript-based libraries (like ReactJS) and frameworks (like Next.js, Remix, and so on).

    Being a loosely typed language, JavaScript imposes the challenge of handling type safety correctly. TypeScript is useful for managing types, but we still need to handle runtime errors efficiently in our code.

    Errors like TypeError, RangeError, ReferenceError are probably pretty familiar to you if you’ve been building with JavaScript for a while. All these errors may cause invalid data, bad page transitions, unwanted results, or even the entire application to crash – none of which will make end users happy!

    In this handbook, you’ll learn everything you need to know about error handling in JavaScript. We will start with an understanding of errors, their types, and occurrences. Then you’ll learn how to deal with these errors so that they don’t cause a bad user experience. At the end, you’ll also learn to build your own custom error types and clean-up methodologies to handle your code flow better for optimizations and performance.

    I hope you enjoy reading along and practising the tasks I have provided at the end of the article.

    This handbook is also available as a video session as part of the 40 Days of JavaScript initiative. Please check it out.

    Table of Contents

    1. Errors in JavaScript

    2. Handling Errors With the try and catch

      • The try Block

      • The catch Block

    3. Error Handling: Real-World Use Cases

      • Handling Division by Zero

      • Handling JSON

    4. Anatomy of the Error Object

      • What is the Error Object?
    5. Throwing Errors and Re-throwing Errors

      • Rethrowing
    6. The finally with try-catch

      • Caution with finally
    7. Custom Errors

      • A Real-World Use Case of Custom Errors
    8. Task Assignments for You

      • Find the Output

      • Payment Process Validation

    9. 40 Days of JavaScript Challenge Initiative

    10. Before We End…

    Errors in JavaScript

    Errors and exceptions are the events that disrupt program execution. JavaScript parses and executes code line by line. The source code gets evaluated with the grammar of the programming language to ensure it is valid and executable. If there is a mismatch, JavaScript encounters a parsing error. You’ll need to make sure you follow the right syntax and grammar of the language to stay away from parsing errors.

    Take a look at the code snippet below. Here, we have made the mistake of not closing the parentheses for the console.log.

    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"hi"</span>
    

    This will lead to a Syntax Error like this:

    Uncaught SyntaxError

    Other types of errors can happen due to wrong data input, trying to read a value or property that doesn’t exist, or acting on inaccurate data. Let’s see some examples:

    <span class="hljs-built_in">console</span>.log(x); <span class="hljs-comment">// Uncaught ReferenceError: x is not defined</span>
    
    <span class="hljs-keyword">let</span> obj = <span class="hljs-literal">null</span>;
    <span class="hljs-built_in">console</span>.log(obj.name); <span class="hljs-comment">// Uncaught TypeError: Cannot read properties of null</span>
    
    <span class="hljs-keyword">let</span> arr = <span class="hljs-keyword">new</span> <span class="hljs-built_in">Array</span>(<span class="hljs-number">-1</span>) <span class="hljs-comment">// Uncaught RangeError: Invalid array length</span>
    
    <span class="hljs-built_in">decodeURIComponent</span>(<span class="hljs-string">"%"</span>); <span class="hljs-comment">// Uncaught URIError: URI malformed</span>
    
    <span class="hljs-built_in">eval</span>(<span class="hljs-string">"var x = ;"</span>); <span class="hljs-comment">// Uncaught EvalError</span>
    

    Here is the list of possible runtime errors you may encounter, along with their descriptions:

    • ReferenceError – Occurs when trying to access a variable that is not defined.

    • TypeError – Occurs when an operation is performed on a value of the wrong type.

    • RangeError – Occurs when a value is outside the allowable range.

    • SyntaxError – Occurs when there is a mistake in the syntax of the JavaScript code.

    • URIError – Occurs when an incorrect URI function is used in encoding and decoding URIs.

    • EvalError – Occurs when there is an issue with the eval() function.

    • InternalError – Occurs when the JavaScript engine runs into an internal limit (stack overflow).

    • AggregateError – Introduced in ES2021, used for handling multiple errors at once.

    • Custom Errors – These are user-defined errors, and we will learn how to create and use them soon.

    Have you noticed that all the code examples we used above result in a message explaining what the error is about? If you look at those messages closely, you will find a word called Uncaught. It means the error occurred, but it was not caught and managed. That’s exactly what we will now go for – so you know how to handle these errors.

    Handling Errors With the try and catch

    JavaScript applications can break for various reasons, like invalid syntax, invalid data, missing API responses, user mistakes, and so on. Most of these reasons may lead to an application crash, and your users will see a blank white page.

    Rather than letting the application crash, you can gracefully handle these situations using try…catch.

    <span class="hljs-keyword">try</span> {
        <span class="hljs-comment">// logic or code</span>
    } <span class="hljs-keyword">catch</span> (err) {
        <span class="hljs-comment">// handle error</span>
    }
    

    The try Block

    The try block contains the code – the business logic – which might throw an error. Developers always want their code to be error-free. But at the same time, you should be aware that the code might throw an error for several possible reasons, like:

    • Parsing JSON

    • Running API logic

    • Accessing nested object properties

    • DOM manipulations

    • … and many more

    When the code inside the try block throws an error, the code execution of the remaining code in the try block will be suspended, and the control moves to the nearest catch block. If no error occurs, the catch block is skipped completely.

    <span class="hljs-keyword">try</span> {
      <span class="hljs-comment">// Code that might throw an error</span>
    } <span class="hljs-keyword">catch</span> (error) {
      <span class="hljs-comment">// Handle the error here</span>
    }
    

    The catch Block

    The catch block runs only if an error was thrown in the try block. It receives the Error object as a parameter to give us more information about the error. In the example shown below, we are using something called abc without declaring it. JavaScript will throw an error like this:

    <span class="hljs-keyword">try</span> {
        <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"execution starts here"</span>);
        abc;
        <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"execution ends here"</span>);
    } <span class="hljs-keyword">catch</span> (err) {
        <span class="hljs-built_in">console</span>.error(<span class="hljs-string">"An Error has occured"</span>, err);
    }
    

    JavaScript executes code line by line. The execution sequence of the above code will be:

    • First, the string “execution starts here” will be logged to the console.

    • Then the control will move to the next line and find the abc there. What is it? JavaScript doesn’t find any definition of it anywhere. It’s time to raise the alarm and throw an error. The control doesn’t move to the next line (the next console log), but rather moves to the catch block.

    • In the catch block, we handle the error by logging it to the console. We could do many other things like show a toast message, send the user an email, or switch off a toaster (why not if your customer needs it).

    Without try…catch, the error would crash the app.

    Error Handling: Real-World Use Cases

    Let’s now see some of the real-world use cases of error handling with try…catch.

    Handling Division by Zero

    Here is a function that divides a number by another number. So, we have parameters passed to the function for both numbers. We want to make sure that the division never encounters an error for dividing a number by zero (0).

    As a proactive measure, we have written a condition that if the divisor is zero, we will throw an error saying that division by zero is not allowed. In every other case, we will proceed with the division operation. In case of an error, the catch block will handle the error and do what’s needed (in this case, logging the error to the console).

    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">divideNumbers</span>(<span class="hljs-params">a, b</span>) </span>{
        <span class="hljs-keyword">try</span> {
            <span class="hljs-keyword">if</span> (b === <span class="hljs-number">0</span>) {
                <span class="hljs-keyword">const</span> err = <span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span>(<span class="hljs-string">"Division by zero is not allowed."</span>);
                <span class="hljs-keyword">throw</span> err;
            }
            <span class="hljs-keyword">const</span> result = a/b;
            <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`The result is <span class="hljs-subst">${result}</span>`</span>);
        } <span class="hljs-keyword">catch</span>(error) {
            <span class="hljs-built_in">console</span>.error(<span class="hljs-string">"Got a Math Error:"</span>, error.message)
        }
    }
    

    Now, if we invoke the function with the following arguments, we will get a result of 5, and the second argument is a non-zero value.

    divideNumbers(<span class="hljs-number">15</span>, <span class="hljs-number">3</span>); <span class="hljs-comment">// The result is 5</span>
    

    But if we pass the 0 value for the second argument, the program will throw an error, and it will be logged into the console.

    divideNumbers(<span class="hljs-number">15</span>, <span class="hljs-number">0</span>);
    

    Output:

    Math Error

    Handling JSON

    Often, you will get JSON as a response to an API call. You need to parse this JSON in your JavaScript code to extract the values. What if the API sends you some malformed JSON by mistake? You cann’t afford to let your user interface crash because of this. You need to handle it gracefully – and here comes the try…catch block again to the rescue:

    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">parseJSONSafely</span>(<span class="hljs-params">str</span>) </span>{
      <span class="hljs-keyword">try</span> {
        <span class="hljs-keyword">return</span> <span class="hljs-built_in">JSON</span>.parse(str);
      } <span class="hljs-keyword">catch</span> (err) {
        <span class="hljs-built_in">console</span>.error(<span class="hljs-string">"Invalid JSON:"</span>, err.message);
        <span class="hljs-keyword">return</span> <span class="hljs-literal">null</span>;
      }
    }
    
    <span class="hljs-keyword">const</span> userData = parseJSONSafely(<span class="hljs-string">'{"name": "tapaScript"}'</span>); <span class="hljs-comment">// Parsed</span>
    <span class="hljs-keyword">const</span> badData = parseJSONSafely(<span class="hljs-string">'name: tapaScript'</span>);         <span class="hljs-comment">// Handled gracefully</span>
    

    Without try…catch, the second call will crash the app.

    Anatomy of the Error Object

    Getting errors in programming can be a scary feeling. But Errors in JavaScript aren’t just some scary, annoying messages – they are structured objects that carry a lot of helpful information about what went wrong, where, and why.

    As developers, we need to understand the anatomy of the Error object to help us better with faster debugging and smarter recovery in production-level application issues.

    Let’s deep dive into the Error object, its properties, and how to use it effectively with examples.

    What is the Error Object?

    The JavaScript engine throws an Error object when something goes wrong during runtime. This object contains helpful information like:

    • An error message: This is a human-readable error message.

    • The error type: TypeError, ReferenceError, SyntaxError, and so on that we discussed above.

    • The stack trace: This helps you navigate to the root of the error. It is a string containing the stack trace at the point the error was thrown.

    Let’s take a look at the code snippet below. The JavaScript engine will throw an error in this code, as the variable y is not defined. The error object contains the error name (type), message, and the stack trace information.

    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">doSomething</span>(<span class="hljs-params"></span>) </span>{
      <span class="hljs-keyword">const</span> x = y + <span class="hljs-number">1</span>; <span class="hljs-comment">// y is not defined</span>
    }
    <span class="hljs-keyword">try</span> {
      doSomething();
    } <span class="hljs-keyword">catch</span> (err) {
      <span class="hljs-built_in">console</span>.log(err.name);    <span class="hljs-comment">// ReferenceError</span>
      <span class="hljs-built_in">console</span>.log(err.message); <span class="hljs-comment">// y is not defined</span>
      <span class="hljs-built_in">console</span>.log(err.stack); <span class="hljs-comment">// ReferenceError: y is not defined</span>
                              <span class="hljs-comment">// at doSomething (<anonymous>:2:13)</span>
                              <span class="hljs-comment">// at <anonymous>:5:3</span>
    }
    

    Tip: If you need any specific properties from the error object, you can use destructuring to do that. Here is an example where we are only interested in the error name and message, not the stack.

    <span class="hljs-keyword">try</span> {
      <span class="hljs-built_in">JSON</span>.parse(<span class="hljs-string">"{ invalid json }"</span>);
    } <span class="hljs-keyword">catch</span> ({name, message}) {
      <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Name:"</span>, name);       <span class="hljs-comment">// Name: SyntaxError</span>
      <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Message:"</span>, message); <span class="hljs-comment">// Message: Expected property name or '}' in JSON at position 2 (line 1 column 3)</span>
    }
    

    Throwing Errors and Re-throwing Errors

    JavaScript provides a throw statement to trigger an error manually. It is very helpful when you want to handle an invalid condition in your code (remember the divide by zero problem?).

    To throw an error, you need to create an instance of the Error object with details and then throw it.

    <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span>(<span class="hljs-string">"Something is bad!"</span>);
    

    When the code execution encounters a throw statement,

    • It stops the execution of the current code block immediately.

    • The control moves to the nearest catch block (if any).

    • If the catch block is not found, the error will not be caught. The error gets bubbled up, and may end up crashing the program. You can learn more in-depth about events and event bubbling from here.

    Rethrowing

    At times, catching the error itself in the catch block is not enough. Sometimes, you may not know how to handle the error completely, and you might want to do additional things, like:

    • Adding more context to the error.

    • Logging the error into a file-based logger.

    • Passing the error to someone more specialized to handle it.

    This is where rethrow comes in. With rethrowing, you catch an error, do something else with it, and then throw it again.

    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">processData</span>(<span class="hljs-params"></span>) </span>{
      <span class="hljs-keyword">try</span> {
        parseUserData();
      } <span class="hljs-keyword">catch</span> (err) {
        <span class="hljs-built_in">console</span>.error(<span class="hljs-string">"Error in processData:"</span>, err.message);
        <span class="hljs-keyword">throw</span> err; <span class="hljs-comment">// Rethrow so the outer function can handle it too</span>
      }
    }
    
    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">main</span>(<span class="hljs-params"></span>) </span>{
      <span class="hljs-keyword">try</span> {
        processData();
      } <span class="hljs-keyword">catch</span> (err) {
        handleErrorBetter(err);
      }
    }
    

    In the code above, the processData() function catches an error, logs it, and then throws it again. The outer main() function can now catch it and do something more to handle it better.

    In the real-world application development, you would want to separate the concerns for errors, like:

    • API Layer – In this layer, you can detect HTTP failures

        <span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">fetchUser</span>(<span class="hljs-params">id</span>) </span>{
          <span class="hljs-keyword">const</span> res = <span class="hljs-keyword">await</span> fetch(<span class="hljs-string">`/users/<span class="hljs-subst">${id}</span>`</span>);
          <span class="hljs-keyword">if</span> (!res.ok) <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span>(<span class="hljs-string">"User not found"</span>); <span class="hljs-comment">// throw it here</span>
          <span class="hljs-keyword">return</span> res.json();
        }
      
    • Service Layer – In this layer, you handle business logic. So the error will be handled for invalid conditions.

        <span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">getUser</span>(<span class="hljs-params">id</span>) </span>{
          <span class="hljs-keyword">try</span> {
            <span class="hljs-keyword">const</span> user = <span class="hljs-keyword">await</span> fetchUser(id);
            <span class="hljs-keyword">return</span> user;
          } <span class="hljs-keyword">catch</span> (err) {
            <span class="hljs-built_in">console</span>.error(<span class="hljs-string">"Fetching user failed:"</span>, err.message);
            <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span>(<span class="hljs-string">"Unable to load user profile"</span>); <span class="hljs-comment">// rethrowing </span>
          }
        }
      
    • UI Layer – Show a user-friendly error message.

        <span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">showUserProfile</span>(<span class="hljs-params"></span>) </span>{
          <span class="hljs-keyword">try</span> {
            <span class="hljs-keyword">const</span> user = <span class="hljs-keyword">await</span> getUser(<span class="hljs-number">123</span>);
            renderUser(user);
          } <span class="hljs-keyword">catch</span> (err) {
            displayError(err.message); <span class="hljs-comment">// A proper message show to the user</span>
          }
        }
      

    The finally with try-catch

    The try…catch block gives us a way to handle errors gracefully. But you may always want to execute some code irrespective of whether an error occurred or not. For example, closing the database connection, stopping a loader, resetting some states, and so on. That’s where finally comes in.

    <span class="hljs-keyword">try</span> {
      <span class="hljs-comment">// Code might throw an error</span>
    } <span class="hljs-keyword">catch</span> (error) {
      <span class="hljs-comment">// Handle the error</span>
    } <span class="hljs-keyword">finally</span> {
      <span class="hljs-comment">// Always runs, whether an error occured or not</span>
    }
    

    Let’s take an example:

    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">performTask</span>(<span class="hljs-params"></span>) </span>{
      <span class="hljs-keyword">try</span> {
        <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Doing something cool..."</span>);
        <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span>(<span class="hljs-string">"Oops!"</span>);
      } <span class="hljs-keyword">catch</span> (err) {
        <span class="hljs-built_in">console</span>.error(<span class="hljs-string">"Caught error:"</span>, err.message);
      } <span class="hljs-keyword">finally</span> {
        <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Cleanup: Task finished (success or fail)."</span>);
      }
    }
    
    performTask();
    

    In the performTask() function, the error is thrown after the first console log. So, the control will move to the catch block and log the error. After that, the finally block will execute its console log.

    Output:

    Doing something cool...
    Caught error: Oops!
    Cleanup: Task finished (success or fail).
    

    Let’s take a more real-world use case of making an API call and handling the loading spinner:

    <span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">loadUserData</span>(<span class="hljs-params"></span>) </span>{
      showSpinner(); <span class="hljs-comment">// Show the spinner here</span>
    
      <span class="hljs-keyword">try</span> {
        <span class="hljs-keyword">const</span> res = <span class="hljs-keyword">await</span> fetch(<span class="hljs-string">'/api/user'</span>);
        <span class="hljs-keyword">const</span> data = <span class="hljs-keyword">await</span> res.json();
        displayUser(data);
      } <span class="hljs-keyword">catch</span> (err) {
        showError(<span class="hljs-string">"Failed to load user."</span>);
      } <span class="hljs-keyword">finally</span> {
        hideSpinner(); <span class="hljs-comment">// Hide spinner for both success and fail cases.</span>
      }
    }
    

    Usually, we show a loading spinner while making an API (asynchronous) call from the browser. Irrespective of the successful response or an error from the API call, we must stop showing the loading spinner. Instead of executing the code logic twice to stop the spinner (once inside the try block and then again inside the catch block), you can do it inside the finally block.

    Caution with finally

    The finally block can override return values or a thrown error. This behaviour may be confusing and can lead to bugs as well.

    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">test</span>(<span class="hljs-params"></span>) </span>{
      <span class="hljs-keyword">try</span> {
        <span class="hljs-keyword">return</span> <span class="hljs-string">'from try'</span>;
      } <span class="hljs-keyword">finally</span> {
        <span class="hljs-keyword">return</span> <span class="hljs-string">'from finally'</span>;
      }
    }
    
    <span class="hljs-built_in">console</span>.log(test());
    

    What do you think the above code returns?

    It will return 'from finally'. The return 'from try' is completely ignored. The return from finally overrides it silently.

    Let’s see one more example of the same problem:

    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">willThrow</span>(<span class="hljs-params"></span>) </span>{
      <span class="hljs-keyword">try</span> {
        <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span>(<span class="hljs-string">"Original Error"</span>);
      } <span class="hljs-keyword">finally</span> {
        <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span>(<span class="hljs-string">"Overriding Error"</span>); <span class="hljs-comment">// The original error is lost</span>
      }
    }
    
    <span class="hljs-keyword">try</span> {
      willThrow();
    } <span class="hljs-keyword">catch</span> (err) {
      <span class="hljs-built_in">console</span>.log(err.message); <span class="hljs-comment">// "Overriding Error"</span>
    }
    

    Here, the original error ("Original Error”) is swallowed. The finally block overrides the actual root cause.

    When using finally:

    • Avoid returns and throws from finally as much as possible.

    • Avoid performing logic in the finally block that may impact the actual outcome. The try block is the best place for that.

    • Any critical decision-making must be avoided inside the finally block

    • Use finally for cleanup activities, such as closing files, connections, and stopping loading spinners, etc.

    • Ensure the finally block contains side-effect-free code.

    Custom Errors

    Using the generic Error and its existing types, like ReferenceError, SyntaxError, and so on, can be a bit vague in complex applications. JavaScript lets you create custom errors that are more related to your business use cases. The custom errors can provide:

    • Additional contextual information about the error.

    • Clarity about the error

    • More readable logs

    • The ability to handle multiple error cases conditionally.

    A custom error in JavaScript is a user-defined error type that extends the built-in Error class. The custom error should be an ES6 Class that extends JavaScript’s Error class. We can use the super() in the constructor function to inherit the message property of the Error class. You can optionally assign a name and clean the stack trace for the custom error.

    <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">MyCustomError</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Error</span> </span>{
      <span class="hljs-keyword">constructor</span>(message) {
        <span class="hljs-built_in">super</span>(message);         <span class="hljs-comment">// Inherit message property</span>
        <span class="hljs-built_in">this</span>.name = <span class="hljs-built_in">this</span>.constructor.name; <span class="hljs-comment">// Optional but recommended</span>
        <span class="hljs-built_in">Error</span>.captureStackTrace(<span class="hljs-built_in">this</span>, <span class="hljs-built_in">this</span>.constructor); <span class="hljs-comment">// Clean stack trace</span>
      }
    }
    

    Let’s now see a real-world use case for a custom error.

    A Real-World Use Case of Custom Errors

    Using a form on a web page is an extremely common use case. A form may contain one or more input fields. It is recommended to validate the user inputs before we process the form data for any server actions.

    Let’s create a custom validation error we can leverage for validating multiple form input data, like the user’s email, age, phone number, and more.

    First, we’ll create a class called ValidationError that extends the Error class. The constructor function sets up the ValidationError class with an error message. We can also instantiate additional properties, like name, field, and so on.

    <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">ValidationError</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Error</span> </span>{
      <span class="hljs-keyword">constructor</span>(field, message) {
        <span class="hljs-built_in">super</span>(<span class="hljs-string">`<span class="hljs-subst">${field}</span>: <span class="hljs-subst">${message}</span>`</span>);
        <span class="hljs-built_in">this</span>.name = <span class="hljs-string">"ValidationError"</span>;
        <span class="hljs-built_in">this</span>.field = field;
      }
    }
    

    Now, let’s see how to use ValidationError. We can validate a user model to check its properties and throw a ValidationError whenever the expectations mismatch.

    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">validateUser</span>(<span class="hljs-params">user</span>) </span>{
      <span class="hljs-keyword">if</span> (!user.email.includes(<span class="hljs-string">"@"</span>)) {
        <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> ValidationError(<span class="hljs-string">"email"</span>, <span class="hljs-string">"Invalid email format"</span>);
      }
      <span class="hljs-keyword">if</span> (!user.age || user.age < <span class="hljs-number">18</span>) {
        <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> ValidationError(<span class="hljs-string">"age"</span>, <span class="hljs-string">"User must be 18+"</span>);
      }
    }
    

    In the code snippet above,

    • We throw an invalid email format validation error if the user’s email doesn’t include the @ symbol.

    • We throw another validation error if the age information of the user is missing or is below 18.

    A custom error gives us the power to create domain/usage-specific error types to keep the code more manageable and less error-prone.

    Task Assignments for You

    If you have read the handbook this far, I hope you now have a solid understanding of JavaScript Error Handling. Let’s try out some assignments based on what we have learned so far. It’s going to be fun.

    Find the Output

    What will be the output of the following code snippet and why?

    <span class="hljs-keyword">try</span> {
        <span class="hljs-keyword">let</span> r = p + <span class="hljs-number">50</span>;
        <span class="hljs-built_in">console</span>.log(r);
    } <span class="hljs-keyword">catch</span> (error) {
        <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"An error occurred:"</span>, error.name);
    }
    

    Options are:

    • ReferenceError

    • SyntaxError

    • TypeError

    • No error, it prints 10

    Payment Process Validation

    Write a function processPayment(amount) that verifies if the amount is positive and does not exceed the balance. If any condition fails, throw appropriate errors.

    Hint: You can think of creating a Custom Error here.

    40 Days of JavaScript Challenge Initiative

    There are 101 ways of learning something. But nothing can beat structured and progressive learning methodologies. After spending more than two decades in Software Engineering, I’ve been able to gather the best of JavaScript together to create the 40 Days of JavaScript challenge initiative.

    Check it out if you want to learn JavaScript with fundamental concepts, projects, and assignments for free (forever). Focusing on the fundamentals of JavaScript will prepare you well for a future in web development.

    Before We End…

    That’s all! I hope you found this article insightful.

    Let’s connect:

    • Subscribe to my YouTube Channel.

    • Follow on LinkedIn if you don’t want to miss the daily dose of up-skilling tips.

    • Check out and follow my open-source work on GitHub.

    See you soon with my next article. Until then, please take care of yourself and keep learning.

    Source: freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More 

    Facebook Twitter Reddit Email Copy Link
    Previous ArticleAfter 24 hours with Samsung’s Galaxy Z Flip 7, one big thing stands out
    Next Article Oops! It’s not you, it’s the Design (sometimes)

    Related Posts

    Development

    Using phpinfo() to Debug Common and Not-so-Common PHP Errors and Warnings

    September 28, 2025
    Development

    Mastering PHP File Uploads: A Guide to php.ini Settings and Code Examples

    September 28, 2025
    Leave A Reply Cancel Reply

    For security, use of Google's reCAPTCHA service is required which is subject to the Google Privacy Policy and Terms of Use.

    Continue Reading

    20+ Best Free Lightroom Mobile Presets for Photographers in 2025

    Learning Resources

    Lightweight, Composable Emoji Picker for React – Frimousse

    Development

    This Android tablet is the best I’ve tested all year – and it’s currently on sale

    News & Updates

    How to Scale TestOps for Global Software Development Teams

    Development

    Highlights

    Machine Learning

    Configure fine-grained access to Amazon Bedrock models using Amazon SageMaker Unified Studio

    July 9, 2025

    Enterprises adopting advanced AI solutions recognize that robust security and precise access control are essential…

    Fine-tune OpenAI GPT-OSS models using Amazon SageMaker HyperPod recipes

    August 22, 2025

    A Coding Guide to Different Function Calling Methods to Create Real-Time, Tool-Enabled Conversational AI Agents

    April 29, 2025

    Exact Match Search with Sitecore Search

    April 17, 2025
    © DevStackTips 2025. All rights reserved.
    • Contact
    • Privacy Policy

    Type above and press Enter to search. Press Esc to cancel.