Silent conversions vs validation at the boundary
Defensive code checks what comes in before using it: guard clauses reject bad input at the top of a function, optional chaining and ?? handle values that may be missing, and anything unexpected fails loudly instead of quietly producing wrong results.
Change the code and press Run (Ctrl+Enter). Predict what will happen first, then break it on purpose and read what changes. Your edits are saved and match the lesson page.
Ready for more? This phase has 5 hands-on exercises with automatic checks.
Practice questions
Write the code in the editor, run it, then open the model answer to compare.
Rewrite with guard clauses so that null throws a TypeError and an empty name returns "Hello, guest": function greet(user) { if (user) { if (user.name) { return "Hello, " + user.name; } else { return "Hello, guest"; } } }
Write discountedPrice(price, percent) that throws a TypeError unless both are finite numbers, throws a RangeError unless percent is between 0 and 100, and returns the price after the discount. Show the result for (200, 10) and the error for (200, 150).
Explain it without notes
What is a guard clause, and why do many developers prefer it to nested if statements?
What is the difference between ?? and ||, and when does it matter?
What is a silent failure? Give two examples and how to avoid them.
Where should you validate data, and why there?
Preview
Console
Nothing logged yet.Expected console output
Number('') = 0 | Number('12abc') = NaN | parseInt('12abc') = 12
OK: 42
OK: 7
Age is required
Age must be a whole number, got "12abc"
Age must be from 0 to 130, got -3
Age must be a whole number, got "4.5"