We see errors everywhere, from our browser console to the terminal of our machine running Node.js.
This shot focuses on outlining the types of errors that we may encounter during
This is thrown when a number is outside an allowable range of values.
const l = console.log
const arr = [90, 88]
arr.length = 90**99
Here we have an arr
array with two elements. Next, we try to grow the array to contain 90**99 == 2.9512665430652753e+193
elements.
This number is way past the size arrays can grow. Therefore running this array will throw a RangeError
as shown below:
$ node errors
errors.js:4
arr.length=90**99
^
RangeError: Invalid array length
This happens because the number to which we want to increase the arr
array is out of the range specified by JS.
This error is thrown when a reference made to a variable/item is broken, which means the variable/item doesn’t exist.
const l=console.log
const cat = "cat"
cat
dog
We have a variable cat
initialized to “cat”
. Next, we refer to the cat
variable and dog
variable. cat
variable exists but the dog
variable doesn’t.
cat
will return “cat”
, while dog
will throw a reference error
because the name dog
cannot be found on the environment record.
$ node errors
errors.js:3
dog
^
ReferenceError: dog is not defined
Whenever we create or define a variable, the variable name will be written to an environment record. This environment record is like key-value storage.
+-------------+
| Key | Value |
---------------
| cat | "cat" |
+-------------+
This stores variables defined in our program for when we reference a variable.
The environment record is searched with the name of the variable as a key. When the key is found in the record, the value is extracted and returned calling a function that hasn’t been defined.
When we create or define a variable var
without assignment, the variable is written to the environment record. The key
is the variable name, but the value
will hold undefined
.
var cat
env record
+-----------------+
| Key | Value |
-------------------
| cat | undefined |
+-----------------+
When the variable is later assigned a value, the variable is searched in the env record
. When the value is found, the initial undefined value is overwritten with the assigned value.
var cat
cat = "cat"
env record
+-------------+
| Key | Value |
---------------
| cat | "cat" |
+-------------+
A RefernceError
is thrown by the JS engine when a variable name is not found in the env record
.
+-------------+
| Key | Value |
---------------
| cat | "cat" |
+-------------+
cat // "cat", yes, :) it's there
dog // :( what's this? can't find it
An undefined variable won’t throw
ReferenceError
because it exists in theenv record
. However, its value hasn’t been set.
This is the most common error we encounter. This error occurs when we type code that the JS engine can’t understand.
This error is caught by the JS engine during parsing. There are different stages in the JS engine that our code is put through before we see those results on the terminal.
Tokenization
Parsing
Interpreting
Tokenization breaks the source of the code into individual units. At this stage, numbers
, keywords
, literals
, operators
are sorted out and individually marked.
Next, the token stream generated will be passed to the parsing stage, which is handled by a parser. This is where an
If the syntax/source of our codes doesn’t conform to the syntax rules of JS during tokenization and parsing, this will make the stages fail and throw SyntaxError
.
const l = console.log
let cat h = "cat"
The isolated h
breaks the code.
$ node errors
errors.js:3
let cat h = "cat"
^
SyntaxError: Unexpected identifier
Here Node.js
points out the problem. It says that the h
was unexpected. It being there breaks the declaration of the cat
variable.
So we can say syntax error occurs during parsing or compile time.
TypeError
is used to indicate an unsuccessful operation when none of the other NativeError
objects are an appropriate indication of the failure cause.
TypeError
occurs when an operation is performed on a wrong data type. Maybe a boolean
is expected, but a string
is found.
If we try to convert a number to uppercase like this:
const num = 123
num.toUpperCase()
It will throw a TypeError
:
$ node errors
errors.js:4
num.toUpperCase()
^
TypeError: num.toUpperCase is not a function
This happens because the toUpperCase()
function expects a string
data type. The toUpperCase()
function is intentionally generic; it does not require this value to be a String
object.
Therefore, the function can be transferred to other kinds of objects for use as a method.
Only strings
are converted to uppercase or lowercase. If we call the toUpperCase()
function on Objects
, Boolean
, Symbol
, null
, undefined
data types, we will get the TypeError
because it is the wrong data type that it operates.
URI (Uniform Resource Indicator) in JS has the functions: decodeURI()
, decodeURIComponent()
, etc.
This indicates that one of the global URI handling functions was used in an incompatible way with its definition.
We will get a URIError
if we call any of them with the wrong parameter:
decodeURI("%")
^
URIError: URI malformed
decodeURI()
gets the unencoded version of a URI. “%”
is not the correct URI, so a URIError
was thrown.
URIError
is thrown when there’s a problem encoding or decoding the URI.
This is used to identify errors when using the global eval()
function.
According to EcmaSpec 2018
edition:
“This exception is not currently used within this specification. This object remains for compatibility with previous editions of this specification.”
This error occurs internally in the JS engine, especially when it has too much data to handle and the stack grows way over its critical limit.
This also occurs when the JS engine is overwhelmed by too many recursions, switch cases, etc.
switch(num) {
case 1:
...
break
case 2:
...
break
case 3:
...
break
case 4:
...
break
case 5:
...
break
case 6:
...
break
case 7:
...
break
... up to 1000 cases
}
There is too much recursion. Here is a simple example:
function foo() {
foo()
}
foo()
We need to know the types of native errors we can throw in order to solve the errors. We have listed them in this shot, with a few examples to show how they are encountered.
Whenever an error is thrown in your terminal or browser, you can easily spot where and how the error occurred. This allows you to write better, less error-prone code.
Free Resources