eval()
function is used
improperly.
encodeURI()
and decodeURI()
encounter a malformed URI.
Promise.any()
.
throw
statement.
throw
any type of object as an Exception, such
as Numbers, Strings, Arrays, etc.
try
, catch
, finally
statements, which gives us control over
the flow of exceptions on our
code.
try
clause is mandatory and wraps a block of
code that potentially can throw an
error.
catch
block, which wraps JavaScript code that
handles the error.
catch
clause stops the exception from
propagating through the call stack and
allows the application flow to continue.
The error itself is passed as an
argument to the catch
clause.
instanceof
operator that can be used to
differentiate between the types of
exceptions:
throw
an exception that has been caught. For
example, if you catch an exception, the
type of which is not relevant to you in
this context.
finally
code block is executed after the try
and catch
clauses, regardless of any exceptions.
The finally
clause is useful for including clean up
code such as closing WebSocket
connections or other resources.
finally
block will be executed even if a thrown
exception is not caught. In such a
scenario, the finally
block is executed, and then the engine
continues to go through the functions in
the call stack in order until the
exception is handled properly or the
application is terminated.
finally
block will be executed even if the try
or catch
blocks execute a return
statement.
foo1()
function, we get false
as result, even though the try
block has a return
statement.
return
statement in a catch
block:
foo2()
also returns false
.
{ "name": "John",
"age": 30 }
; Internally, we’ll use JSON.parse. If
it receives malformed json, then it
throws SyntaxError. But even if json is
syntactically correct, that doesn’t mean
that it’s a valid user, right? It may
miss the necessary data. For instance,
it may not have name and age properties
that are essential for our users.
async
function, a rejected promise will be
returned with the thrown error,
equivalent to:
foo()
is invoked:
foo()
is async
, it dispatches a Promise
. The code does not wait for the async
function, so there is no actual error to
be caught at the moment. The finally
block is executed and then the Promise
rejects.
Promise
.
await
keyword when invoking foo()
and wrapping the code in an async
function:
Promise
:
foo
with a string
instead of a number
:
Uncaught TypeError: x is not a
number
since the catch
of the promise is not being able to
handle an error that was thrown outside
of the Promise
.
try
and catch
clauses:
foo
is modified to throw an error inside of
the Promise
:
catch
statement of the promise will handle the
error:
Promise
is the same thing as using the reject
callback. So it's better to define foo
like this:
catch
method to handle the error inside the Promise
, the next function from the callback
queue will be added to the stack.
err
argument. If no error occurred, err
will be set to null
.
err
object, it's better not to touch or
rely on the result
parameter.
window.onerror
event handler that can be used for this
purpose.
Uncaught ReferenceError: foo is
not defined
.
window.onerror
because it is a function assignment, and
there can only be one function assigned
to an event at a time.
window.onerror
, you will override any previous
handler that might have been assigned by
third-party libraries. This can be a
huge problem, especially for tools such
as error trackers, as they will most
likely completely stop working.
window.onerror
, and simply calls it before
proceeding. Using this pattern, you can
keep adding additional handlers to window.onerror
.
window
object:
process
object from the EventEmmiter
module provides two events for handling
errors.
uncaughtException
--- emitted when an uncaught
exception bubbles all the way
back to the
event loop. By default, Node.js handles
such exceptions by printing the
stack trace to stderr and
exiting with code 1
. Adding a handler for this
event overrides the default
behavior. The correct use of the
event is to perform synchronous
cleanup of allocated resources
(e.g. file descriptors, handles,
etc) before shutting down the
process. It is not safe to
resume normal operation
afterwards.
unhandledRejection
--- emitted whenever a Promise
is rejected and no error handler
is attached to the promise
within a turn of the
event loop. The unhandledRejection
event is useful for detecting
and keeping track of promises
that were rejected and which
rejections have not yet been
handled.
setTimeout
and setInterval
methods can accept?
setTimeout
method return in the Node
environment?
setTimeout
method returns a Timeout object
that can be passed to clearTimeout
to cancel the timeout.
setTimeout
method return in the browser
environment?
setTimeout
method returns a number
representing the unique ID
associated with that timeout.
The ID number can be passed to clearTimeout
to cancel the callback from
running.
test
function to be async
, and we need to prepend the callack
invocation with await
.
--require ./[file].js
flag allows files to be required before
executing scripts with the node
command
"Refactoring is the process of changing a software system in such a way that it does not alter the external behavior of the code yet improves its internal structure." --- Martin Fowler
UNIT TESTING is a level of software testing where individual units/ components of a software are tested. The purpose is to validate that each unit of the software performs as designed. A unit is the smallest testable part of any software. It usually has one or a few inputs and usually a single output. In procedural programming, a unit may be an individual program, function, procedure, etc. In object-oriented programming, the smallest unit is a method, which may belong to a base/ super class, abstract class or derived/ child class. See More about unit testing here
add, subtract, multiply
and you want to do it with TDD.
add
method. If we run this test, it will
fail, showing something like this:
-1
, decimal numbers 0.4
, really big numbers 10000000000000000000...00
or even unexpected values like strings,
arrays, undefined
number-game-errors.html
open in, and open your
JavaScript console. You should
see an error message along the
following lines:addEventListener()
]docs/Web/API/EventTarget/addEventListener).
addeventListener
to addEventListener
should fix this. Do this
now.
Null
]docs/Glossary/Null) is a
special value that means
"nothing", or "no
value". So lowOrHi
has been declared and
initialised, but not with any
meaningful value --- it has no
type or value.
checkGuess() { ... }
block). As you'll learn in
more detail in our later
[functions
article]docs/Learn/JavaScript/Building_blocks/Functions),
code inside functions runs in a
separate scope than code outside
functions. In this case, the
code was not run and the error
was not thrown until the checkGuess()
function was run by line
86.
textContent
property of the lowOrHi
constant to a text string, but
it's not working because lowOrHi
does not contain what it's
supposed to. Let's see why
this is --- try searching for
other instances of lowOrHi
in the code. The earliest
instance you'll find in the
JavaScript is on line 48:
null
after this line has been run.
Add the following code on line
49:
console.log()
]docs/Web/API/console/log) is a
really useful debugging function
that prints a value to the
console. So it will print the
value of lowOrHi
to the console as soon as we
have tried to set it in line
48.
console.log()
result in your console.lowOrHi
's value is null
at this point, so there is
definitely a problem with line
48.
document.querySelector()
]docs/Web/API/Document/querySelector)
method to get a reference to an
element by selecting it with a
CSS selector. Looking further up
our file, we can find the
paragraph in question:
.
), but the selector being
passed into the querySelector()
method in line 48 has no dot.
This could be the problem! Try
changing lowOrHi
to .lowOrHi
in line 48.
console.log()
statement should return the <p>
element we want. Phew! Another
error fixed! You can delete your console.log()
line now, or keep it to
reference later on --- your
choice.
Error
objects are thrown when runtime errors
occur. The Error
object can also be used as a base object
for user-defined exceptions. See below
for standard built-in error types.
Error
objects being created and thrown.
Error
constructor, there are other core error
constructors in JavaScript. For
client-side exceptions, see
Exception handling statements.
encodeURI()
or
decodeURI()
are passed invalid parameters.
Promise.any()
.
Error
object.
Error.captureStackTrace()
Error.prototype.description
Error.prototype.number
addeventListener
to .addEventListener
. Do this now.
randomNumber
variable, and the lines where
the random number is first set.
The instance that stores the
random number that we want to
guess at the start of the game
should be around line number
44:
console.log()
again --- insert the following
line directly below each of the
above two lines:
randomNumber
is equal to 1 at each point
where it is logged to the
console.
Math.random()
]/Math/random), which generates a
random decimal number between 0 and 1,
e.g. 0.5675493843.
Math.random()
through [Math.floor()
]/Math/floor), which rounds the number
passed to it down to the nearest whole
number. We then add 1 to that
result:
checkGuess()
function:
=
) --- which sets a variable to be equal
to a value --- with the strict equality
operator (===
), which tests whether one value is
equal to another, and returns a true
/false
result.
checkGuess()
:
true
, causing the program to report that
the game has been won. Be careful!
checkGuess()
function.
objects are thrown when runtime errors
occur. The
Error` object can also be used as a
base object for user-defined exceptions.
See below for standard built-in error
types.
Error
objects being created and thrown.
Error
constructor, there are other core error
constructors in JavaScript. For
client-side exceptions, see [Exception
handling
statements]Guide/Control_flow_and_error_handling#exception_handling_statements).
EvalError
]/EvalError)
eval()
]/eval).
RangeError
]/RangeError)
ReferenceError
]/ReferenceError)
SyntaxError
]/SyntaxError)
TypeError
]/TypeError)
URIError
]/URIError)
encodeURI()
]/encodeURI) or [decodeURI()
]/decodeURI) are passed invalid
parameters.
AggregateError
]/AggregateError)
Promise.any()
]/Promise/any).
InternalError
]/InternalError)
Error()
]/Error/Error)
Error
object.
Error
object with the intention of raising it
using the [throw
]Reference/Statements/throw) keyword.
You can handle the error using the
[try...catch
]Reference/Statements/try...catch)
construct:
constructor
]/Object/constructor) property or, if
you're writing for modern
JavaScript engines, [instanceof
]Reference/Operators/instanceof)
keyword:
Error
objects that have more specific
messages. The original error should be
passed to the new Error
in the constructor option
parameter (cause
property), as this ensures that the
original error and stack trace are
available to higher level try/catch
blocks.
doFailSomeWay()
and doFailAnotherWay()
):
cause
property in [custom error
types]/error#custom_error_types),
provided the subclasses'
constructor passes the options
parameter when calling super()
:
Error
to be able to throw new MyError()
and use instanceof MyError
to check the kind of error in the
exception handler. This results in
cleaner and more consistent error
handling code.
CustomError
class methods, but only when they are
declared with
[Object.defineProperty()]/Object/defineProperty).
Otherwise, old versions of Babel and
other transpilers will not correctly
handle the following code without
additional configuration.
CustomError
constructor in the stack trace when
using ES2015 classes.
http://great.jokes/christmas
) that you can call to a get list of
Christmas jokes in JSON format.
apiUrl
and jokeId
which returns a promise.
id
.
saySetup
and sayPunchLine
methods.
new Error('No jokes found
id: {jokeId}')
.
new Error('No jokes at
url: {url}')
for an unexpected shape.
fetch(url)
function, which implements the basics of
the fetch api.
Learn about fetch.
Learn about async/await.
lint-staged
error
will exit the process and fail a
build.
warn
will continue to run the process and not
fail a build.
off
will ignore the rule entirely.
extends
property. eslint:recommended
is a built-in config.
env
property can be used to set the
environment against which files should
be evaluated.
prettier
can be used to format code in files via
CLI:
prettier
can be used to format markdown and
graphql, too.
prettier
allows for a .prettierignore
to ignore formatting of generated
files
extend
ed eslint configs take precedence from
the end of the array.
rules
in the the eslint config take precedence
over any extensions.
prettier
can be run with a --list-different
flag which exits with a non-zero code if
there are any files that are not
formatted correctly. This can be used
with ghooks
to ensure all team members are using prettier
.
--
operator:
@flow
at the top of files that you want to use flow
to make type strict after installing flow-bin
as a dev dependency.
husky
works in a similar way to ghooks
, except that you add npm scripts to
run pre and post-hooks.
lint-staged
lint-staged
not only allows linters to be run on
precommit, but allows one to define
commands to be run should linting pass,
allowing for repo owners to have
autoformatting run and changed files
staged without relying on collaborators
to have autoformatters enabled.
thumb-war
and utils
, and mock out utils.getWinner
so that we can evaluate other aspects of thumb-war
. We are making utils.getWinner
deterministic, as the randomness of what
it usually returns will affect the
outcomes of our tests in
non-deterministic ways.
jest.fn
which takes a mock implementation, and
accepts all arguments passed to
it.
mock
object where we can store calls to the
mock function.
jest.fn
.
toHaveBeenCalledWith
, toHaveBeenNthCalledWith
, or to inspect mockFn.mock.calls
to inspect how the function was used for
all calls.
jest.spyOn
to create a mock implementation. This
mitigates us having to store the
original function and replace it, as
Jest will do the heavy lifting for
us.
jest.spyOn(myObject,
'myObjectFn')
myObject.myObjectFn.mockImplementation(mockFn)
to create a mock implementation
of myObjectFn
myObject.myObjectFn.mockRestore()
to replace the mock
implementation with the original
so that other tests are not
affected. .mockRestore()
restores the mock implementation
to its pre-mocked
definition
jest.spyOn
is still a form of monkey-patching.
Monkey-patching is great for our own
modules, because we're using
commonjs's require
. When working in an es environment
we'll have to mock an entire
module, and jest.mock
allows one to do this.
jest.mock
we can create the mock implementation
inside of the mock, and no longer need
to use jest.spyOn
and [fnToMock].mockImplementation
.
mock.mockRestore()
to restore the mock implementation, we
now use mock.mockReset()
. mock.mockRestore()
is only available for mocks created with jest.spyOn
jest.mock
can be placed anywhere in the file, and
Jest will hoist it to the top of the
file.
jest.mock
takes control of the entire module
requiring system. This can be simulated
using require.cache
. require.cache
is an object that has keys for each
import, with each key being associated
with an object containining information
regarding the import.
exports
property to create the mock
implementation of the module
__mocks__
folder. Node modules can be placed in
the root
__mocks__
that Jest inspects, by default adjacent
to node_modules
. For user-defined modules
they can be placed in a __mocks__
folder adjacent to the module. The mock
must use the same filename as the mocked
module.
jest.mock('./path/to/mock')
must be added to the test file.
require.cache
. We create a file containing the mock,
which also uses our fn
to allow us to evaluate calls. In our
test we import our mock, and then
retrieve the cached paths for the actual
utils and mock utils, rewriting require.cache
's key for the actual utils with
the mocked utils.
git branch add-my-new-file git add my-new-file.js git commit -m "Add new file" git push -u origin add-my-new-file This is the typical push workflow.
git diff master feature
git diff 1fc345a 2e3dff
git diff 1fc345a 2e3dff my-file.js Time Travel checkout
git checkout master
git checkout 7d3e2f1
git checkout -
git checkout HEAD~3 Git Do-over: Reset and Rebase Git Reset : Can be used to travel back in time before a bug or error occured. --soft : appended to reset to move our HEAD ref to the commit we specified - does not touch our code, only resets commit messages.(least dangerous!) --mixed : Default state of Git reset, changes are preserved but they are removed from the commit history straight to the working directory. --hard : Adjust head ref and totally destroy any interim code changes Rebase: An Alternative Form of Time Travel