Computer Programming 1 (JavaScript) • Data I/O & JSON

JSON Error Handling — I can handle JSON parse errors with try/catch at my level and explain what caused the error.

Learn to gracefully catch and diagnose JSON parsing failures so your programs never crash unexpectedly.

A JavaScript data file with code brackets and a laptop.
Inside this lesson 10 sections 5 questions 6 figures

SECTION 1

Historical Context & Motivation

In the early days of programming, when something went wrong, the entire program would simply crash. There was no elegant way to say, "Hey, something broke — let me handle it and keep going." As software grew more complex and began exchanging data across networks, error handling became essential. Programs needed to anticipate problems — especially when dealing with data from the outside world — and recover from them gracefully instead of just halting.

The rise of JSON (JavaScript Object Notation) as the dominant data exchange format made this need even more urgent. When your JavaScript program receives JSON data from a web API, a file, or user input, that data arrives as a plain text string. If even a single character is out of place — a missing comma, a rogue single-quote, or a trailing comma — the JSON.parse() function will throw an error and crash your program. This is exactly the kind of problem that try/catch was designed to solve.

1960s • Early Error Codes

Programs used numeric return codes to signal success or failure. Developers had to check these codes manually after every operation, leading to cluttered and error-prone code.

1995 • JavaScript Is Born

Brendan Eich creates JavaScript at Netscape. Early versions lacked structured error handling, so runtime errors would simply halt script execution in the browser.

1999 • try/catch Added to JavaScript

ECMAScript 3 introduces the try/catch/finally statement, giving JavaScript developers a structured way to intercept and recover from runtime errors.

2001 • JSON Introduced by Douglas Crockford

Douglas Crockford formalizes JSON as a lightweight data interchange format derived from JavaScript object syntax. It quickly becomes the standard for web APIs.

2009 • JSON.parse() Standardized

ECMAScript 5 adds the native JSON.parse() and JSON.stringify() methods, making JSON handling built-in and setting the stage for robust error handling with try/catch.

Today, virtually every web application exchanges JSON data. The central question this lesson addresses is: What happens when the JSON data your program receives is malformed, and how do you handle that failure without crashing?

SECTION 2

Core Principles & Definitions

Before you can handle JSON errors, you need to understand a few foundational ideas. These concepts form the toolkit you will use every time you work with external data in JavaScript.

1

JSON.parse()

A built-in JavaScript function that takes a string of valid JSON and converts it into a JavaScript object or array. If the string is not valid JSON, it throws a SyntaxError.
2

Exceptions (Errors)

An exception is a runtime event that disrupts normal program flow. In JavaScript, when an error is "thrown," execution stops immediately unless the error is "caught" by a handler.
3

try/catch Statement

A control structure that lets you try risky code and catch any errors that occur, preventing the program from crashing and letting you respond to the failure.
4

The Error Object

When an error is caught, JavaScript provides an Error object with properties like name (the type of error) and message (a description of what went wrong).
5

Graceful Degradation

The practice of designing programs that continue to function — possibly in a limited way — even when something goes wrong, rather than crashing entirely.
✦

KEY TAKEAWAY

Think of try/catch like a safety net under a trapeze artist. The try block is where the performer does their risky moves (like parsing JSON). If they fall (an error is thrown), the catch block is the safety net that catches them, preventing a disaster. Without the net, one mistake means the whole show stops.

SECTION 3

Visual Explanation — The try/catch Flow

try/catch Execution Flowtry { JSON.parse(str) }Is the JSON valid?NO — Error thrownYES — Successcatch (error) {console.log(error.message)}Success Pathconst data = result;// use data normallyProgram continues running ✓Either way, the program does NOT crash.
This flowchart shows the two possible paths when JSON.parse() runs inside a try block. If the JSON is valid (green path), execution continues normally. If the JSON is invalid (red path), the error is caught, handled, and the program still continues.

The diagram above illustrates the most important idea in this lesson: whether parsing succeeds or fails, your program keeps running. Without try/catch, a single malformed JSON string would crash your entire program. With it, you can detect the problem, inform the user, log the issue, or provide a default value — and then keep going. Notice that the catch block receives an error object that contains a message explaining exactly what went wrong. This is your diagnostic tool.

SECTION 4

How try/catch Works with JSON.parse()

The Basic Structure

The try/catch statement has a straightforward structure. You place the "risky" code inside the try block. If that code throws an error, JavaScript immediately jumps to the catch block, skipping any remaining code in the try block. The catch block receives the error as a parameter, which you can inspect to understand what went wrong.

TRY/CATCH SYNTAX PATTERN

tryriskycodecatch(error)recoverycodetry { risky code } catch (error) { recovery code }

try — wraps code that might throw an error. catch (error) — receives the Error object if an error occurs. error.name — the type of error (e.g., "SyntaxError"). error.message — a human-readable description of what went wrong.

Common JSON Errors and Their Causes

JSON has strict formatting rules. Unlike JavaScript object literals, JSON requires double quotes around keys and string values, does not allow trailing commas, and does not support comments. When these rules are violated, JSON.parse() throws a SyntaxError with a message that points to the issue.

Invalid JSON StringError MessageWhat Went Wrong
{'name': 'Jo'}Expected property name or '}'Single quotes used instead of double quotes
{"a": 1,}Expected property name or '}'Trailing comma after the last property
{name: "Jo"}Expected property name or '}'Property name not wrapped in double quotes
undefinedUnexpected token 'u'The string "undefined" is not valid JSON
Unexpected end of JSON inputAn empty string contains no JSON at all

Common JSON parse errors and their root causes

💡

Remember

Valid JSON uses double quotes only for strings and keys, has no trailing commas, and does not allow comments or undefined values. If you remember these rules, you can predict most JSON errors before they happen.

SECTION 5

Anatomy of a JSON Error

When JSON.parse() fails, it doesn't just say "something went wrong." It creates a detailed SyntaxError object with properties you can use to diagnose the problem. Understanding how to read these properties is the key to writing useful error messages for yourself and your users.

Anatomy of a JSON SyntaxError// Broken JSON stringconst bad = '{ "name": "Ava", "age": }';▼ passed to JSON.parse(bad) inside try blockSyntaxError Objecterror.name→ "SyntaxError"The type of error that occurrederror.message→ "Expected value at position 24"A human-readable explanation of the problemerror.stack→ Full stack trace showing where the error happenedUseful for debugging — shows the line number{ "name": "Ava", "age": }↑ Missing value after "age":
This diagram breaks down the three key properties of the Error object you receive in the catch block: name tells you the error type, message describes the specific problem, and stack shows the call stack for debugging.

The error.message property is your most valuable clue. It often tells you the exact position in the string where parsing failed and what the parser expected to find instead. For example, "Unexpected token } at position 24" tells you that at character 24, the parser found a closing brace when it was expecting a value. You can use this information to look back at the original JSON string and pinpoint the mistake. In the example above, "age": is followed immediately by } — a value is missing after the colon.

  • error.name — For JSON parse failures, this is always "SyntaxError"
  • error.message — Describes the exact problem and often the character position
  • error.stack — The full stack trace, useful when debugging complex applications

SECTION 6

Worked Example — Handling a JSON Parse Error

Let's walk through a realistic scenario. Imagine you're building a web app that loads user profile data. The data arrives as a JSON string, but sometimes the data source sends malformed JSON. Your job is to handle this safely.

Safely Parsing User Profile JSON

  1. 1

    Step 1 — Identify the Input

    We receive a JSON string from an external source. In this case, the string has a bug — a trailing comma after the last property. The input is: '{"username": "alex99", "level": 12,}'
    This string has a trailing comma after 12, which is invalid JSON.
  2. 2

    Step 2 — Wrap JSON.parse() in a try Block

    We place the call to JSON.parse() inside a try block. We also declare a variable before the try block to hold the result: let profile = null; Then inside the try: profile = JSON.parse(jsonString);
    The risky operation is now protected by the try block.
  3. 3

    Step 3 — Write the catch Block

    In the catch block, we receive the error object and log a helpful message: catch (error) { console.error("Failed to parse JSON:", error.message); } This prints the error type and description without crashing the program.
    Output: Failed to parse JSON: Expected property name or '}'
  4. 4

    Step 4 — Provide a Fallback

    After the try/catch, we check whether profile is still null. If it is, we use a default profile: if (profile === null) { profile = { username: "guest", level: 1 }; }
    The program continues running with a safe default value instead of crashing.
  5. 5

    Step 5 — Complete Code

    Here is the full solution: const jsonString = '{"username": "alex99", "level": 12,}'; let profile = null; try { profile = JSON.parse(jsonString); } catch (error) { console.error("Parse failed:", error.message); } if (profile === null) { profile = { username: "guest", level: 1 }; } console.log(profile.username); // outputs: "guest"
    The program handles the error gracefully and continues with a default profile.

SECTION 7

With vs. Without Error Handling

To truly appreciate why try/catch matters, let's compare what happens when you do and don't use it. The difference is the difference between a robust application and a fragile one.

AspectWithout try/catchWith try/catch
What happens on bad JSONProgram crashes immediately with an uncaught SyntaxErrorError is caught, logged, and the program continues
User experienceThe page breaks, buttons stop working, or the app freezesA helpful error message is shown, or a default value is used
Debugging abilityYou see a raw error in the console but no context about what data caused itYou can log the bad input alongside the error message for easy diagnosis
Code after JSON.parse()Never executes — everything below the crash point is skippedExecutes normally after the catch block finishes
Professional qualityLooks like a student project — unreliableLooks like production-quality code — resilient and thoughtful

Impact of error handling on program behavior

✦

KEY TAKEAWAY

Think of it like driving a car. Without try/catch, hitting a pothole totals your car — you stop and can't continue your trip. With try/catch, your car has good suspension — you feel the bump, you know it happened, but you keep driving. Professional developers always wrap JSON.parse() in a try/catch because you can never fully trust data from external sources.

SECTION 8

Connection to Advanced Error Handling

The try/catch pattern you've learned here is the foundation for all error handling in JavaScript. As you advance, you'll encounter more sophisticated techniques that build on this foundation. Understanding these connections now will give you a clearer picture of where you're headed.

What You Know NowWhat Comes Next
try/catch for synchronous errors.catch() and async/await for asynchronous errors (Promises)
Catching built-in errors like SyntaxErrorCreating custom error classes with class ValidationError extends Error
Logging errors with console.error()Sending error reports to monitoring services like Sentry or Datadog
Providing fallback values when parsing failsValidating JSON structure against a schema (e.g., using libraries like Joi or Zod)
Handling one error at a timeGlobal error handlers with window.onerror and process.on('uncaughtException')

How today's concepts connect to advanced error handling

One important concept to preview is the finally block. You can add a finally block after your catch, and it will run no matter what — whether the try succeeded or the catch handled an error. This is useful for cleanup tasks, like hiding a loading spinner or closing a file. The pattern becomes: try { ... } catch (e) { ... } finally { ... }. As you move into asynchronous JavaScript and working with APIs, the ability to handle errors will become one of the most important skills in your toolkit.

ℹ

Looking Ahead

When you start using fetch() to get data from web APIs, you will use async/await with try/catch. The pattern is almost identical to what you learned today — the only difference is that the function is marked async and the risky operation uses await. Your try/catch foundation transfers directly.

SECTION 9

Practice Problems

Question 1: CONCEPTUAL

In your own words, explain why you should always wrap JSON.parse() inside a try/catch block when the JSON string comes from an external source (like user input or an API).
Show answer
When JSON comes from an external source, you cannot guarantee that it will be properly formatted. Users might type invalid data, APIs might return error pages instead of JSON, or network issues could corrupt the data mid-transfer. Without try/catch, JSON.parse() will throw an uncaught SyntaxError that crashes the entire program. By wrapping it in try/catch, you give your code the ability to detect the failure, inform the user or log the problem, and continue running — perhaps by providing a default value or asking the user to try again.

Question 2: BASIC CALCULATION

What will the following code output to the console? Explain why. try { const data = JSON.parse('{"score": 95}'); console.log(data.score); } catch (error) { console.log("Error: " + error.message); }
Show answer
The output will be 95. The JSON string {"score": 95} is perfectly valid — it uses double quotes around the key, the value is a number (which doesn't need quotes), and there are no trailing commas. Since JSON.parse() succeeds without throwing an error, the catch block is never executed. The code proceeds to console.log(data.score), which prints 95.

Question 3: INTERMEDIATE

The following JSON string has an error. Identify the error, predict what error.message would say, and write a try/catch block that handles it by setting a default value. const input = '{"items": ["apple", "banana",]}';
Show answer
The error is a trailing comma after "banana" inside the array. JSON does not allow trailing commas. The error.message would be something like "Expected a JSON value" or "Unexpected token ]" (exact wording varies by JavaScript engine). A correct try/catch solution would be: let cart = null; try { cart = JSON.parse(input); } catch (error) { console.error("Invalid JSON:", error.message); cart = { items: [] }; } console.log(cart.items); This catches the error, logs a diagnostic message, and provides a fallback object with an empty items array so the rest of the program can continue safely.

Question 4: APPLIED

You are building a settings page where users can paste JSON to configure their app. Write a function called loadSettings(jsonString) that: 1. Tries to parse the JSON string. 2. If successful, returns the parsed object. 3. If it fails, logs the error message and returns a default settings object: { theme: "light", fontSize: 14 }.
Show answer
Here is the complete function: function loadSettings(jsonString) { try { const settings = JSON.parse(jsonString); return settings; } catch (error) { console.error("Settings parse error:", error.message); return { theme: "light", fontSize: 14 }; } } This function wraps JSON.parse() in a try block. If the input is valid JSON (e.g., '{"theme": "dark", "fontSize": 18}'), the parsed object is returned. If the input is malformed (e.g., the user pastes broken text), the catch block logs a helpful error message and returns the default settings. This ensures the app always has usable settings, regardless of what the user pastes.

Question 5: CRITICAL THINKING

Consider this code: try { const data = JSON.parse('{"name": "Sam"}'); console.log(data.age.toUpperCase()); } catch (error) { console.log(error.name + ": " + error.message); } The JSON is valid, so JSON.parse() will succeed. However, the catch block will still run. Explain what error occurs, what error.name will be, and why this shows that try/catch catches more than just JSON parse errors.
Show answer
The JSON string is valid and parses successfully into { name: "Sam" }. However, the next line tries to access data.age, which is undefined because there is no "age" property. Then .toUpperCase() is called on undefined, which throws a TypeError (not a SyntaxError). The output will be "TypeError: Cannot read properties of undefined (reading 'toUpperCase')". This demonstrates that try/catch catches ANY error thrown inside the try block, not just JSON-related ones. This is both powerful and something to be aware of — if you put too much code in your try block, you might catch errors you didn't expect and mask real bugs. Best practice is to keep only the JSON.parse() call and closely related code inside the try block.

SUMMARY

Lesson Summary

Summary

In this lesson, you learned that JSON.parse() converts a JSON string into a JavaScript object, but it will throw a SyntaxError if the input is not valid JSON. Common causes of invalid JSON include single quotes instead of double quotes, trailing commas, unquoted keys, and missing values. To prevent these errors from crashing your program, you wrap the parse call in a try/catch block.

The catch block receives an Error object with name and message properties that tell you exactly what went wrong. You can use this information to log the error, display a user-friendly message, or provide a fallback default value. This pattern — try the risky operation, catch and handle the failure — is the cornerstone of graceful error handling in JavaScript and a skill you will use throughout your programming career.

Varsity Tutors • Computer Programming 1 (JavaScript) • JSON Error Handling