An alias of ok.
Node.js module
assert
The 'node:assert'
module provides a simple set of assertion tests for validating invariants in code. It includes functions like assert.ok
, assert.strictEqual
, and assert.throws
to perform runtime checks and throw descriptive errors when assertions fail.
Assertions are commonly used in tests and internal sanity checks to ensure that expected values and conditions hold true during execution. The module supports deep equality checks, custom error messages, and strict or loose comparisons.
Works in Bun
Fully implemented.
- @param value
The input that is checked for being truthy.
namespace strict
In strict assertion mode, non-strict methods behave like their corresponding strict methods. For example, deepEqual will behave like deepStrictEqual.
In strict assertion mode, error messages for objects display a diff. In legacy assertion mode, error messages for objects display the objects, often truncated.
To use strict assertion mode:
import { strict as assert } from 'node:assert'; import assert from 'node:assert/strict';
Example error diff:
import { strict as assert } from 'node:assert'; assert.deepEqual([[[1, 2, 3]], 4, 5], [[[1, 2, '3']], 4, 5]); // AssertionError: Expected inputs to be strictly deep-equal: // + actual - expected ... Lines skipped // // [ // [ // ... // 2, // + 3 // - '3' // ], // ... // 5 // ]
To deactivate the colors, use the
NO_COLOR
orNODE_DISABLE_COLORS
environment variables. This will also deactivate the colors in the REPL. For more on color support in terminal environments, read the ttygetColorDepth()
documentation.class AssertionError
Indicates the failure of an assertion. All errors thrown by the
node:assert
module will be instances of theAssertionError
class.- static prepareStackTrace?: (err: Error, stackTraces: CallSite[]) => any
Optional override for formatting stack traces
- targetObject: object,constructorOpt?: Function): void;
Creates a
.stack
property ontargetObject
, which when accessed returns a string representing the location in the code at whichError.captureStackTrace()
was called.const myObject = {}; Error.captureStackTrace(myObject); myObject.stack; // Similar to `new Error().stack`
The first line of the trace will be prefixed with
${myObject.name}: ${myObject.message}
.The optional
constructorOpt
argument accepts a function. If given, all frames aboveconstructorOpt
, includingconstructorOpt
, will be omitted from the generated stack trace.The
constructorOpt
argument is useful for hiding implementation details of error generation from the user. For instance:function a() { b(); } function b() { c(); } function c() { // Create an error without stack trace to avoid calculating the stack trace twice. const { stackTraceLimit } = Error; Error.stackTraceLimit = 0; const error = new Error(); Error.stackTraceLimit = stackTraceLimit; // Capture the stack trace above function b Error.captureStackTrace(error, b); // Neither function c, nor b is included in the stack trace throw error; } a();
interface CallTrackerCall
- type AssertPredicate = RegExp | new () => object | (thrown: unknown) => boolean | object | Error
- actual: unknown,expected: unknown,): void;
Strict assertion mode
An alias of deepStrictEqual.
Legacy assertion mode
Stability: 3 - Legacy: Use deepStrictEqual instead.
Tests for deep equality between the
actual
andexpected
parameters. Consider using deepStrictEqual instead. deepEqual can have surprising results.Deep equality means that the enumerable "own" properties of child objects are also recursively evaluated by the following rules.
- actual: unknown,expected: T,): asserts actual is T;
Tests for deep equality between the
actual
andexpected
parameters. "Deep" equality means that the enumerable "own" properties of child objects are recursively evaluated also by the following rules. - value: string,regExp: RegExp,): void;
Expects the
string
input not to match the regular expression.import assert from 'node:assert/strict'; assert.doesNotMatch('I will fail', /fail/); // AssertionError [ERR_ASSERTION]: The input was expected to not match the ... assert.doesNotMatch(123, /pass/); // AssertionError [ERR_ASSERTION]: The "string" argument must be of type string. assert.doesNotMatch('I will pass', /different/); // OK
If the values do match, or if the
string
argument is of another type thanstring
, an{@link AssertionError}
is thrown with amessage
property set equal to the value of themessage
parameter. If themessage
parameter is undefined, a default error message is assigned. If themessage
parameter is an instance of an Error then it will be thrown instead of the{@link AssertionError}
. - block: Promise<unknown> | () => Promise<unknown>,): Promise<void>;
Awaits the
asyncFn
promise or, ifasyncFn
is a function, immediately calls the function and awaits the returned promise to complete. It will then check that the promise is not rejected.If
asyncFn
is a function and it throws an error synchronously,assert.doesNotReject()
will return a rejectedPromise
with that error. If the function does not return a promise,assert.doesNotReject()
will return a rejectedPromise
with an ERR_INVALID_RETURN_VALUE error. In both cases the error handler is skipped.Using
assert.doesNotReject()
is actually not useful because there is little benefit in catching a rejection and then rejecting it again. Instead, consider adding a comment next to the specific code path that should not reject and keep error messages as expressive as possible.If specified,
error
can be aClass
,RegExp
, or a validation function. See throws for more details.Besides the async nature to await the completion behaves identically to doesNotThrow.
import assert from 'node:assert/strict'; await assert.doesNotReject( async () => { throw new TypeError('Wrong value'); }, SyntaxError, );
import assert from 'node:assert/strict'; assert.doesNotReject(Promise.reject(new TypeError('Wrong value'))) .then(() => { // ... });
block: Promise<unknown> | () => Promise<unknown>,): Promise<void>;Awaits the
asyncFn
promise or, ifasyncFn
is a function, immediately calls the function and awaits the returned promise to complete. It will then check that the promise is not rejected.If
asyncFn
is a function and it throws an error synchronously,assert.doesNotReject()
will return a rejectedPromise
with that error. If the function does not return a promise,assert.doesNotReject()
will return a rejectedPromise
with an ERR_INVALID_RETURN_VALUE error. In both cases the error handler is skipped.Using
assert.doesNotReject()
is actually not useful because there is little benefit in catching a rejection and then rejecting it again. Instead, consider adding a comment next to the specific code path that should not reject and keep error messages as expressive as possible.If specified,
error
can be aClass
,RegExp
, or a validation function. See throws for more details.Besides the async nature to await the completion behaves identically to doesNotThrow.
import assert from 'node:assert/strict'; await assert.doesNotReject( async () => { throw new TypeError('Wrong value'); }, SyntaxError, );
import assert from 'node:assert/strict'; assert.doesNotReject(Promise.reject(new TypeError('Wrong value'))) .then(() => { // ... });
- block: () => unknown,): void;
Asserts that the function
fn
does not throw an error.Using
assert.doesNotThrow()
is actually not useful because there is no benefit in catching an error and then rethrowing it. Instead, consider adding a comment next to the specific code path that should not throw and keep error messages as expressive as possible.When
assert.doesNotThrow()
is called, it will immediately call thefn
function.If an error is thrown and it is the same type as that specified by the
error
parameter, then anAssertionError
is thrown. If the error is of a different type, or if theerror
parameter is undefined, the error is propagated back to the caller.If specified,
error
can be aClass
,RegExp
, or a validation function. See throws for more details.The following, for instance, will throw the
TypeError
because there is no matching error type in the assertion:import assert from 'node:assert/strict'; assert.doesNotThrow( () => { throw new TypeError('Wrong value'); }, SyntaxError, );
However, the following will result in an
AssertionError
with the message 'Got unwanted exception...':import assert from 'node:assert/strict'; assert.doesNotThrow( () => { throw new TypeError('Wrong value'); }, TypeError, );
If an
AssertionError
is thrown and a value is provided for themessage
parameter, the value ofmessage
will be appended to theAssertionError
message:import assert from 'node:assert/strict'; assert.doesNotThrow( () => { throw new TypeError('Wrong value'); }, /Wrong value/, 'Whoops', ); // Throws: AssertionError: Got unwanted exception: Whoops
block: () => unknown,): void;Asserts that the function
fn
does not throw an error.Using
assert.doesNotThrow()
is actually not useful because there is no benefit in catching an error and then rethrowing it. Instead, consider adding a comment next to the specific code path that should not throw and keep error messages as expressive as possible.When
assert.doesNotThrow()
is called, it will immediately call thefn
function.If an error is thrown and it is the same type as that specified by the
error
parameter, then anAssertionError
is thrown. If the error is of a different type, or if theerror
parameter is undefined, the error is propagated back to the caller.If specified,
error
can be aClass
,RegExp
, or a validation function. See throws for more details.The following, for instance, will throw the
TypeError
because there is no matching error type in the assertion:import assert from 'node:assert/strict'; assert.doesNotThrow( () => { throw new TypeError('Wrong value'); }, SyntaxError, );
However, the following will result in an
AssertionError
with the message 'Got unwanted exception...':import assert from 'node:assert/strict'; assert.doesNotThrow( () => { throw new TypeError('Wrong value'); }, TypeError, );
If an
AssertionError
is thrown and a value is provided for themessage
parameter, the value ofmessage
will be appended to theAssertionError
message:import assert from 'node:assert/strict'; assert.doesNotThrow( () => { throw new TypeError('Wrong value'); }, /Wrong value/, 'Whoops', ); // Throws: AssertionError: Got unwanted exception: Whoops
- actual: unknown,expected: unknown,): void;
Strict assertion mode
An alias of strictEqual.
Legacy assertion mode
Stability: 3 - Legacy: Use strictEqual instead.
Tests shallow, coercive equality between the
actual
andexpected
parameters using the==
operator.NaN
is specially handled and treated as being identical if both sides areNaN
.import assert from 'node:assert'; assert.equal(1, 1); // OK, 1 == 1 assert.equal(1, '1'); // OK, 1 == '1' assert.equal(NaN, NaN); // OK assert.equal(1, 2); // AssertionError: 1 == 2 assert.equal({ a: { b: 1 } }, { a: { b: 1 } }); // AssertionError: { a: { b: 1 } } == { a: { b: 1 } }
If the values are not equal, an
AssertionError
is thrown with amessage
property set equal to the value of themessage
parameter. If themessage
parameter is undefined, a default error message is assigned. If themessage
parameter is an instance of anError
then it will be thrown instead of theAssertionError
. - value: unknown): asserts value is undefined | null;
Throws
value
ifvalue
is notundefined
ornull
. This is useful when testing theerror
argument in callbacks. The stack trace contains all frames from the error passed toifError()
including the potential new frames forifError()
itself.import assert from 'node:assert/strict'; assert.ifError(null); // OK assert.ifError(0); // AssertionError [ERR_ASSERTION]: ifError got unwanted exception: 0 assert.ifError('error'); // AssertionError [ERR_ASSERTION]: ifError got unwanted exception: 'error' assert.ifError(new Error()); // AssertionError [ERR_ASSERTION]: ifError got unwanted exception: Error // Create some random error frames. let err; (function errorFrame() { err = new Error('test error'); })(); (function ifErrorFrame() { assert.ifError(err); })(); // AssertionError [ERR_ASSERTION]: ifError got unwanted exception: test error // at ifErrorFrame // at errorFrame
- value: string,regExp: RegExp,): void;
Expects the
string
input to match the regular expression.import assert from 'node:assert/strict'; assert.match('I will fail', /pass/); // AssertionError [ERR_ASSERTION]: The input did not match the regular ... assert.match(123, /pass/); // AssertionError [ERR_ASSERTION]: The "string" argument must be of type string. assert.match('I will pass', /pass/); // OK
If the values do not match, or if the
string
argument is of another type thanstring
, an{@link AssertionError}
is thrown with amessage
property set equal to the value of themessage
parameter. If themessage
parameter is undefined, a default error message is assigned. If themessage
parameter is an instance of an Error then it will be thrown instead of the{@link AssertionError}
. - actual: unknown,expected: unknown,): void;
Strict assertion mode
An alias of notDeepStrictEqual.
Legacy assertion mode
Stability: 3 - Legacy: Use notDeepStrictEqual instead.
Tests for any deep inequality. Opposite of deepEqual.
import assert from 'node:assert'; const obj1 = { a: { b: 1, }, }; const obj2 = { a: { b: 2, }, }; const obj3 = { a: { b: 1, }, }; const obj4 = { __proto__: obj1 }; assert.notDeepEqual(obj1, obj1); // AssertionError: { a: { b: 1 } } notDeepEqual { a: { b: 1 } } assert.notDeepEqual(obj1, obj2); // OK assert.notDeepEqual(obj1, obj3); // AssertionError: { a: { b: 1 } } notDeepEqual { a: { b: 1 } } assert.notDeepEqual(obj1, obj4); // OK
If the values are deeply equal, an
AssertionError
is thrown with amessage
property set equal to the value of themessage
parameter. If themessage
parameter is undefined, a default error message is assigned. If themessage
parameter is an instance of anError
then it will be thrown instead of theAssertionError
. - actual: unknown,expected: unknown,): void;
Tests for deep strict inequality. Opposite of deepStrictEqual.
import assert from 'node:assert/strict'; assert.notDeepStrictEqual({ a: 1 }, { a: '1' }); // OK
If the values are deeply and strictly equal, an
AssertionError
is thrown with amessage
property set equal to the value of themessage
parameter. If themessage
parameter is undefined, a default error message is assigned. If themessage
parameter is an instance of anError
then it will be thrown instead of theAssertionError
. - actual: unknown,expected: unknown,): void;
Strict assertion mode
An alias of notStrictEqual.
Legacy assertion mode
Stability: 3 - Legacy: Use notStrictEqual instead.
Tests shallow, coercive inequality with the
!=
operator.NaN
is specially handled and treated as being identical if both sides areNaN
.import assert from 'node:assert'; assert.notEqual(1, 2); // OK assert.notEqual(1, 1); // AssertionError: 1 != 1 assert.notEqual(1, '1'); // AssertionError: 1 != '1'
If the values are equal, an
AssertionError
is thrown with amessage
property set equal to the value of themessage
parameter. If themessage
parameter is undefined, a default error message is assigned. If themessage
parameter is an instance of anError
then it will be thrown instead of theAssertionError
. - actual: unknown,expected: unknown,): void;
Tests strict inequality between the
actual
andexpected
parameters as determined byObject.is()
.import assert from 'node:assert/strict'; assert.notStrictEqual(1, 2); // OK assert.notStrictEqual(1, 1); // AssertionError [ERR_ASSERTION]: Expected "actual" to be strictly unequal to: // // 1 assert.notStrictEqual(1, '1'); // OK
If the values are strictly equal, an
AssertionError
is thrown with amessage
property set equal to the value of themessage
parameter. If themessage
parameter is undefined, a default error message is assigned. If themessage
parameter is an instance of anError
then it will be thrown instead of theAssertionError
. - value: unknown,): asserts value;
Tests if
value
is truthy. It is equivalent toassert.equal(!!value, true, message)
.If
value
is not truthy, anAssertionError
is thrown with amessage
property set equal to the value of themessage
parameter. If themessage
parameter isundefined
, a default error message is assigned. If themessage
parameter is an instance of anError
then it will be thrown instead of theAssertionError
. If no arguments are passed in at allmessage
will be set to the string:'No value argument passed to `assert.ok()`'
.Be aware that in the
repl
the error message will be different to the one thrown in a file! See below for further details.import assert from 'node:assert/strict'; assert.ok(true); // OK assert.ok(1); // OK assert.ok(); // AssertionError: No value argument passed to `assert.ok()` assert.ok(false, 'it\'s false'); // AssertionError: it's false // In the repl: assert.ok(typeof 123 === 'string'); // AssertionError: false == true // In a file (e.g. test.js): assert.ok(typeof 123 === 'string'); // AssertionError: The expression evaluated to a falsy value: // // assert.ok(typeof 123 === 'string') assert.ok(false); // AssertionError: The expression evaluated to a falsy value: // // assert.ok(false) assert.ok(0); // AssertionError: The expression evaluated to a falsy value: // // assert.ok(0)
import assert from 'node:assert/strict'; // Using `assert()` works the same: assert(0); // AssertionError: The expression evaluated to a falsy value: // // assert(0)
- actual: unknown,expected: unknown,): void;
Tests for partial deep equality between the
actual
andexpected
parameters. "Deep" equality means that the enumerable "own" properties of child objects are recursively evaluated also by the following rules. "Partial" equality means that only properties that exist on theexpected
parameter are going to be compared.This method always passes the same test cases as
assert.deepStrictEqual()
, behaving as a super set of it. - block: Promise<unknown> | () => Promise<unknown>,): Promise<void>;
Awaits the
asyncFn
promise or, ifasyncFn
is a function, immediately calls the function and awaits the returned promise to complete. It will then check that the promise is rejected.If
asyncFn
is a function and it throws an error synchronously,assert.rejects()
will return a rejectedPromise
with that error. If the function does not return a promise,assert.rejects()
will return a rejectedPromise
with an ERR_INVALID_RETURN_VALUE error. In both cases the error handler is skipped.Besides the async nature to await the completion behaves identically to throws.
If specified,
error
can be aClass
,RegExp
, a validation function, an object where each property will be tested for, or an instance of error where each property will be tested for including the non-enumerablemessage
andname
properties.If specified,
message
will be the message provided by the{@link AssertionError}
if theasyncFn
fails to reject.import assert from 'node:assert/strict'; await assert.rejects( async () => { throw new TypeError('Wrong value'); }, { name: 'TypeError', message: 'Wrong value', }, );
import assert from 'node:assert/strict'; await assert.rejects( async () => { throw new TypeError('Wrong value'); }, (err) => { assert.strictEqual(err.name, 'TypeError'); assert.strictEqual(err.message, 'Wrong value'); return true; }, );
import assert from 'node:assert/strict'; assert.rejects( Promise.reject(new Error('Wrong value')), Error, ).then(() => { // ... });
error
cannot be a string. If a string is provided as the second argument, thenerror
is assumed to be omitted and the string will be used formessage
instead. This can lead to easy-to-miss mistakes. Please read the example in throws carefully if using a string as the second argument gets considered.block: Promise<unknown> | () => Promise<unknown>,): Promise<void>;Awaits the
asyncFn
promise or, ifasyncFn
is a function, immediately calls the function and awaits the returned promise to complete. It will then check that the promise is rejected.If
asyncFn
is a function and it throws an error synchronously,assert.rejects()
will return a rejectedPromise
with that error. If the function does not return a promise,assert.rejects()
will return a rejectedPromise
with an ERR_INVALID_RETURN_VALUE error. In both cases the error handler is skipped.Besides the async nature to await the completion behaves identically to throws.
If specified,
error
can be aClass
,RegExp
, a validation function, an object where each property will be tested for, or an instance of error where each property will be tested for including the non-enumerablemessage
andname
properties.If specified,
message
will be the message provided by the{@link AssertionError}
if theasyncFn
fails to reject.import assert from 'node:assert/strict'; await assert.rejects( async () => { throw new TypeError('Wrong value'); }, { name: 'TypeError', message: 'Wrong value', }, );
import assert from 'node:assert/strict'; await assert.rejects( async () => { throw new TypeError('Wrong value'); }, (err) => { assert.strictEqual(err.name, 'TypeError'); assert.strictEqual(err.message, 'Wrong value'); return true; }, );
import assert from 'node:assert/strict'; assert.rejects( Promise.reject(new Error('Wrong value')), Error, ).then(() => { // ... });
error
cannot be a string. If a string is provided as the second argument, thenerror
is assumed to be omitted and the string will be used formessage
instead. This can lead to easy-to-miss mistakes. Please read the example in throws carefully if using a string as the second argument gets considered. - actual: unknown,expected: T,): asserts actual is T;
Tests strict equality between the
actual
andexpected
parameters as determined byObject.is()
.import assert from 'node:assert/strict'; assert.strictEqual(1, 2); // AssertionError [ERR_ASSERTION]: Expected inputs to be strictly equal: // // 1 !== 2 assert.strictEqual(1, 1); // OK assert.strictEqual('Hello foobar', 'Hello World!'); // AssertionError [ERR_ASSERTION]: Expected inputs to be strictly equal: // + actual - expected // // + 'Hello foobar' // - 'Hello World!' // ^ const apples = 1; const oranges = 2; assert.strictEqual(apples, oranges, `apples ${apples} !== oranges ${oranges}`); // AssertionError [ERR_ASSERTION]: apples 1 !== oranges 2 assert.strictEqual(1, '1', new TypeError('Inputs are not identical')); // TypeError: Inputs are not identical
If the values are not strictly equal, an
AssertionError
is thrown with amessage
property set equal to the value of themessage
parameter. If themessage
parameter is undefined, a default error message is assigned. If themessage
parameter is an instance of anError
then it will be thrown instead of theAssertionError
. - block: () => unknown,): void;
Expects the function
fn
to throw an error.If specified,
error
can be aClass
,RegExp
, a validation function, a validation object where each property will be tested for strict deep equality, or an instance of error where each property will be tested for strict deep equality including the non-enumerablemessage
andname
properties. When using an object, it is also possible to use a regular expression, when validating against a string property. See below for examples.If specified,
message
will be appended to the message provided by theAssertionError
if thefn
call fails to throw or in case the error validation fails.Custom validation object/error instance:
import assert from 'node:assert/strict'; const err = new TypeError('Wrong value'); err.code = 404; err.foo = 'bar'; err.info = { nested: true, baz: 'text', }; err.reg = /abc/i; assert.throws( () => { throw err; }, { name: 'TypeError', message: 'Wrong value', info: { nested: true, baz: 'text', }, // Only properties on the validation object will be tested for. // Using nested objects requires all properties to be present. Otherwise // the validation is going to fail. }, ); // Using regular expressions to validate error properties: assert.throws( () => { throw err; }, { // The `name` and `message` properties are strings and using regular // expressions on those will match against the string. If they fail, an // error is thrown. name: /^TypeError$/, message: /Wrong/, foo: 'bar', info: { nested: true, // It is not possible to use regular expressions for nested properties! baz: 'text', }, // The `reg` property contains a regular expression and only if the // validation object contains an identical regular expression, it is going // to pass. reg: /abc/i, }, ); // Fails due to the different `message` and `name` properties: assert.throws( () => { const otherErr = new Error('Not found'); // Copy all enumerable properties from `err` to `otherErr`. for (const [key, value] of Object.entries(err)) { otherErr[key] = value; } throw otherErr; }, // The error's `message` and `name` properties will also be checked when using // an error as validation object. err, );
Validate instanceof using constructor:
import assert from 'node:assert/strict'; assert.throws( () => { throw new Error('Wrong value'); }, Error, );
Validate error message using
RegExp
:Using a regular expression runs
.toString
on the error object, and will therefore also include the error name.import assert from 'node:assert/strict'; assert.throws( () => { throw new Error('Wrong value'); }, /^Error: Wrong value$/, );
Custom error validation:
The function must return
true
to indicate all internal validations passed. It will otherwise fail with anAssertionError
.import assert from 'node:assert/strict'; assert.throws( () => { throw new Error('Wrong value'); }, (err) => { assert(err instanceof Error); assert(/value/.test(err)); // Avoid returning anything from validation functions besides `true`. // Otherwise, it's not clear what part of the validation failed. Instead, // throw an error about the specific validation that failed (as done in this // example) and add as much helpful debugging information to that error as // possible. return true; }, 'unexpected error', );
error
cannot be a string. If a string is provided as the second argument, thenerror
is assumed to be omitted and the string will be used formessage
instead. This can lead to easy-to-miss mistakes. Using the same message as the thrown error message is going to result in anERR_AMBIGUOUS_ARGUMENT
error. Please read the example below carefully if using a string as the second argument gets considered:import assert from 'node:assert/strict'; function throwingFirst() { throw new Error('First'); } function throwingSecond() { throw new Error('Second'); } function notThrowing() {} // The second argument is a string and the input function threw an Error. // The first case will not throw as it does not match for the error message // thrown by the input function! assert.throws(throwingFirst, 'Second'); // In the next example the message has no benefit over the message from the // error and since it is not clear if the user intended to actually match // against the error message, Node.js throws an `ERR_AMBIGUOUS_ARGUMENT` error. assert.throws(throwingSecond, 'Second'); // TypeError [ERR_AMBIGUOUS_ARGUMENT] // The string is only used (as message) in case the function does not throw: assert.throws(notThrowing, 'Second'); // AssertionError [ERR_ASSERTION]: Missing expected exception: Second // If it was intended to match for the error message do this instead: // It does not throw because the error messages match. assert.throws(throwingSecond, /Second$/); // If the error message does not match, an AssertionError is thrown. assert.throws(throwingFirst, /Second$/); // AssertionError [ERR_ASSERTION]
Due to the confusing error-prone notation, avoid a string as the second argument.
block: () => unknown,): void;Expects the function
fn
to throw an error.If specified,
error
can be aClass
,RegExp
, a validation function, a validation object where each property will be tested for strict deep equality, or an instance of error where each property will be tested for strict deep equality including the non-enumerablemessage
andname
properties. When using an object, it is also possible to use a regular expression, when validating against a string property. See below for examples.If specified,
message
will be appended to the message provided by theAssertionError
if thefn
call fails to throw or in case the error validation fails.Custom validation object/error instance:
import assert from 'node:assert/strict'; const err = new TypeError('Wrong value'); err.code = 404; err.foo = 'bar'; err.info = { nested: true, baz: 'text', }; err.reg = /abc/i; assert.throws( () => { throw err; }, { name: 'TypeError', message: 'Wrong value', info: { nested: true, baz: 'text', }, // Only properties on the validation object will be tested for. // Using nested objects requires all properties to be present. Otherwise // the validation is going to fail. }, ); // Using regular expressions to validate error properties: assert.throws( () => { throw err; }, { // The `name` and `message` properties are strings and using regular // expressions on those will match against the string. If they fail, an // error is thrown. name: /^TypeError$/, message: /Wrong/, foo: 'bar', info: { nested: true, // It is not possible to use regular expressions for nested properties! baz: 'text', }, // The `reg` property contains a regular expression and only if the // validation object contains an identical regular expression, it is going // to pass. reg: /abc/i, }, ); // Fails due to the different `message` and `name` properties: assert.throws( () => { const otherErr = new Error('Not found'); // Copy all enumerable properties from `err` to `otherErr`. for (const [key, value] of Object.entries(err)) { otherErr[key] = value; } throw otherErr; }, // The error's `message` and `name` properties will also be checked when using // an error as validation object. err, );
Validate instanceof using constructor:
import assert from 'node:assert/strict'; assert.throws( () => { throw new Error('Wrong value'); }, Error, );
Validate error message using
RegExp
:Using a regular expression runs
.toString
on the error object, and will therefore also include the error name.import assert from 'node:assert/strict'; assert.throws( () => { throw new Error('Wrong value'); }, /^Error: Wrong value$/, );
Custom error validation:
The function must return
true
to indicate all internal validations passed. It will otherwise fail with anAssertionError
.import assert from 'node:assert/strict'; assert.throws( () => { throw new Error('Wrong value'); }, (err) => { assert(err instanceof Error); assert(/value/.test(err)); // Avoid returning anything from validation functions besides `true`. // Otherwise, it's not clear what part of the validation failed. Instead, // throw an error about the specific validation that failed (as done in this // example) and add as much helpful debugging information to that error as // possible. return true; }, 'unexpected error', );
error
cannot be a string. If a string is provided as the second argument, thenerror
is assumed to be omitted and the string will be used formessage
instead. This can lead to easy-to-miss mistakes. Using the same message as the thrown error message is going to result in anERR_AMBIGUOUS_ARGUMENT
error. Please read the example below carefully if using a string as the second argument gets considered:import assert from 'node:assert/strict'; function throwingFirst() { throw new Error('First'); } function throwingSecond() { throw new Error('Second'); } function notThrowing() {} // The second argument is a string and the input function threw an Error. // The first case will not throw as it does not match for the error message // thrown by the input function! assert.throws(throwingFirst, 'Second'); // In the next example the message has no benefit over the message from the // error and since it is not clear if the user intended to actually match // against the error message, Node.js throws an `ERR_AMBIGUOUS_ARGUMENT` error. assert.throws(throwingSecond, 'Second'); // TypeError [ERR_AMBIGUOUS_ARGUMENT] // The string is only used (as message) in case the function does not throw: assert.throws(notThrowing, 'Second'); // AssertionError [ERR_ASSERTION]: Missing expected exception: Second // If it was intended to match for the error message do this instead: // It does not throw because the error messages match. assert.throws(throwingSecond, /Second$/); // If the error message does not match, an AssertionError is thrown. assert.throws(throwingFirst, /Second$/); // AssertionError [ERR_ASSERTION]
Due to the confusing error-prone notation, avoid a string as the second argument.
- value: unknown,): asserts value;
An alias of ok.
@param valueThe input that is checked for being truthy.
namespace strict
In strict assertion mode, non-strict methods behave like their corresponding strict methods. For example, deepEqual will behave like deepStrictEqual.
In strict assertion mode, error messages for objects display a diff. In legacy assertion mode, error messages for objects display the objects, often truncated.
To use strict assertion mode:
import { strict as assert } from 'node:assert'; import assert from 'node:assert/strict';
Example error diff:
import { strict as assert } from 'node:assert'; assert.deepEqual([[[1, 2, 3]], 4, 5], [[[1, 2, '3']], 4, 5]); // AssertionError: Expected inputs to be strictly deep-equal: // + actual - expected ... Lines skipped // // [ // [ // ... // 2, // + 3 // - '3' // ], // ... // 5 // ]
To deactivate the colors, use the
NO_COLOR
orNODE_DISABLE_COLORS
environment variables. This will also deactivate the colors in the REPL. For more on color support in terminal environments, read the ttygetColorDepth()
documentation.class AssertionError
Indicates the failure of an assertion. All errors thrown by the
node:assert
module will be instances of theAssertionError
class.- static prepareStackTrace?: (err: Error, stackTraces: CallSite[]) => any
Optional override for formatting stack traces
- targetObject: object,constructorOpt?: Function): void;
Creates a
.stack
property ontargetObject
, which when accessed returns a string representing the location in the code at whichError.captureStackTrace()
was called.const myObject = {}; Error.captureStackTrace(myObject); myObject.stack; // Similar to `new Error().stack`
The first line of the trace will be prefixed with
${myObject.name}: ${myObject.message}
.The optional
constructorOpt
argument accepts a function. If given, all frames aboveconstructorOpt
, includingconstructorOpt
, will be omitted from the generated stack trace.The
constructorOpt
argument is useful for hiding implementation details of error generation from the user. For instance:function a() { b(); } function b() { c(); } function c() { // Create an error without stack trace to avoid calculating the stack trace twice. const { stackTraceLimit } = Error; Error.stackTraceLimit = 0; const error = new Error(); Error.stackTraceLimit = stackTraceLimit; // Capture the stack trace above function b Error.captureStackTrace(error, b); // Neither function c, nor b is included in the stack trace throw error; } a();
interface CallTrackerCall
type AssertPredicate = RegExp | new () => object | (thrown: unknown) => boolean | object | Erroractual: unknown,expected: unknown,): void;Strict assertion mode
An alias of deepStrictEqual.
Legacy assertion mode
Stability: 3 - Legacy: Use deepStrictEqual instead.
Tests for deep equality between the
actual
andexpected
parameters. Consider using deepStrictEqual instead. deepEqual can have surprising results.Deep equality means that the enumerable "own" properties of child objects are also recursively evaluated by the following rules.
actual: unknown,expected: T,): asserts actual is T;Tests for deep equality between the
actual
andexpected
parameters. "Deep" equality means that the enumerable "own" properties of child objects are recursively evaluated also by the following rules.value: string,regExp: RegExp,): void;Expects the
string
input not to match the regular expression.import assert from 'node:assert/strict'; assert.doesNotMatch('I will fail', /fail/); // AssertionError [ERR_ASSERTION]: The input was expected to not match the ... assert.doesNotMatch(123, /pass/); // AssertionError [ERR_ASSERTION]: The "string" argument must be of type string. assert.doesNotMatch('I will pass', /different/); // OK
If the values do match, or if the
string
argument is of another type thanstring
, an{@link AssertionError}
is thrown with amessage
property set equal to the value of themessage
parameter. If themessage
parameter is undefined, a default error message is assigned. If themessage
parameter is an instance of an Error then it will be thrown instead of the{@link AssertionError}
.block: Promise<unknown> | () => Promise<unknown>,): Promise<void>;Awaits the
asyncFn
promise or, ifasyncFn
is a function, immediately calls the function and awaits the returned promise to complete. It will then check that the promise is not rejected.If
asyncFn
is a function and it throws an error synchronously,assert.doesNotReject()
will return a rejectedPromise
with that error. If the function does not return a promise,assert.doesNotReject()
will return a rejectedPromise
with an ERR_INVALID_RETURN_VALUE error. In both cases the error handler is skipped.Using
assert.doesNotReject()
is actually not useful because there is little benefit in catching a rejection and then rejecting it again. Instead, consider adding a comment next to the specific code path that should not reject and keep error messages as expressive as possible.If specified,
error
can be aClass
,RegExp
, or a validation function. See throws for more details.Besides the async nature to await the completion behaves identically to doesNotThrow.
import assert from 'node:assert/strict'; await assert.doesNotReject( async () => { throw new TypeError('Wrong value'); }, SyntaxError, );
import assert from 'node:assert/strict'; assert.doesNotReject(Promise.reject(new TypeError('Wrong value'))) .then(() => { // ... });
block: Promise<unknown> | () => Promise<unknown>,): Promise<void>;Awaits the
asyncFn
promise or, ifasyncFn
is a function, immediately calls the function and awaits the returned promise to complete. It will then check that the promise is not rejected.If
asyncFn
is a function and it throws an error synchronously,assert.doesNotReject()
will return a rejectedPromise
with that error. If the function does not return a promise,assert.doesNotReject()
will return a rejectedPromise
with an ERR_INVALID_RETURN_VALUE error. In both cases the error handler is skipped.Using
assert.doesNotReject()
is actually not useful because there is little benefit in catching a rejection and then rejecting it again. Instead, consider adding a comment next to the specific code path that should not reject and keep error messages as expressive as possible.If specified,
error
can be aClass
,RegExp
, or a validation function. See throws for more details.Besides the async nature to await the completion behaves identically to doesNotThrow.
import assert from 'node:assert/strict'; await assert.doesNotReject( async () => { throw new TypeError('Wrong value'); }, SyntaxError, );
import assert from 'node:assert/strict'; assert.doesNotReject(Promise.reject(new TypeError('Wrong value'))) .then(() => { // ... });
block: () => unknown,): void;Asserts that the function
fn
does not throw an error.Using
assert.doesNotThrow()
is actually not useful because there is no benefit in catching an error and then rethrowing it. Instead, consider adding a comment next to the specific code path that should not throw and keep error messages as expressive as possible.When
assert.doesNotThrow()
is called, it will immediately call thefn
function.If an error is thrown and it is the same type as that specified by the
error
parameter, then anAssertionError
is thrown. If the error is of a different type, or if theerror
parameter is undefined, the error is propagated back to the caller.If specified,
error
can be aClass
,RegExp
, or a validation function. See throws for more details.The following, for instance, will throw the
TypeError
because there is no matching error type in the assertion:import assert from 'node:assert/strict'; assert.doesNotThrow( () => { throw new TypeError('Wrong value'); }, SyntaxError, );
However, the following will result in an
AssertionError
with the message 'Got unwanted exception...':import assert from 'node:assert/strict'; assert.doesNotThrow( () => { throw new TypeError('Wrong value'); }, TypeError, );
If an
AssertionError
is thrown and a value is provided for themessage
parameter, the value ofmessage
will be appended to theAssertionError
message:import assert from 'node:assert/strict'; assert.doesNotThrow( () => { throw new TypeError('Wrong value'); }, /Wrong value/, 'Whoops', ); // Throws: AssertionError: Got unwanted exception: Whoops
block: () => unknown,): void;Asserts that the function
fn
does not throw an error.Using
assert.doesNotThrow()
is actually not useful because there is no benefit in catching an error and then rethrowing it. Instead, consider adding a comment next to the specific code path that should not throw and keep error messages as expressive as possible.When
assert.doesNotThrow()
is called, it will immediately call thefn
function.If an error is thrown and it is the same type as that specified by the
error
parameter, then anAssertionError
is thrown. If the error is of a different type, or if theerror
parameter is undefined, the error is propagated back to the caller.If specified,
error
can be aClass
,RegExp
, or a validation function. See throws for more details.The following, for instance, will throw the
TypeError
because there is no matching error type in the assertion:import assert from 'node:assert/strict'; assert.doesNotThrow( () => { throw new TypeError('Wrong value'); }, SyntaxError, );
However, the following will result in an
AssertionError
with the message 'Got unwanted exception...':import assert from 'node:assert/strict'; assert.doesNotThrow( () => { throw new TypeError('Wrong value'); }, TypeError, );
If an
AssertionError
is thrown and a value is provided for themessage
parameter, the value ofmessage
will be appended to theAssertionError
message:import assert from 'node:assert/strict'; assert.doesNotThrow( () => { throw new TypeError('Wrong value'); }, /Wrong value/, 'Whoops', ); // Throws: AssertionError: Got unwanted exception: Whoops
actual: unknown,expected: unknown,): void;Strict assertion mode
An alias of strictEqual.
Legacy assertion mode
Stability: 3 - Legacy: Use strictEqual instead.
Tests shallow, coercive equality between the
actual
andexpected
parameters using the==
operator.NaN
is specially handled and treated as being identical if both sides areNaN
.import assert from 'node:assert'; assert.equal(1, 1); // OK, 1 == 1 assert.equal(1, '1'); // OK, 1 == '1' assert.equal(NaN, NaN); // OK assert.equal(1, 2); // AssertionError: 1 == 2 assert.equal({ a: { b: 1 } }, { a: { b: 1 } }); // AssertionError: { a: { b: 1 } } == { a: { b: 1 } }
If the values are not equal, an
AssertionError
is thrown with amessage
property set equal to the value of themessage
parameter. If themessage
parameter is undefined, a default error message is assigned. If themessage
parameter is an instance of anError
then it will be thrown instead of theAssertionError
.value: unknown): asserts value is undefined | null;Throws
value
ifvalue
is notundefined
ornull
. This is useful when testing theerror
argument in callbacks. The stack trace contains all frames from the error passed toifError()
including the potential new frames forifError()
itself.import assert from 'node:assert/strict'; assert.ifError(null); // OK assert.ifError(0); // AssertionError [ERR_ASSERTION]: ifError got unwanted exception: 0 assert.ifError('error'); // AssertionError [ERR_ASSERTION]: ifError got unwanted exception: 'error' assert.ifError(new Error()); // AssertionError [ERR_ASSERTION]: ifError got unwanted exception: Error // Create some random error frames. let err; (function errorFrame() { err = new Error('test error'); })(); (function ifErrorFrame() { assert.ifError(err); })(); // AssertionError [ERR_ASSERTION]: ifError got unwanted exception: test error // at ifErrorFrame // at errorFrame
value: string,regExp: RegExp,): void;Expects the
string
input to match the regular expression.import assert from 'node:assert/strict'; assert.match('I will fail', /pass/); // AssertionError [ERR_ASSERTION]: The input did not match the regular ... assert.match(123, /pass/); // AssertionError [ERR_ASSERTION]: The "string" argument must be of type string. assert.match('I will pass', /pass/); // OK
If the values do not match, or if the
string
argument is of another type thanstring
, an{@link AssertionError}
is thrown with amessage
property set equal to the value of themessage
parameter. If themessage
parameter is undefined, a default error message is assigned. If themessage
parameter is an instance of an Error then it will be thrown instead of the{@link AssertionError}
.actual: unknown,expected: unknown,): void;Strict assertion mode
An alias of notDeepStrictEqual.
Legacy assertion mode
Stability: 3 - Legacy: Use notDeepStrictEqual instead.
Tests for any deep inequality. Opposite of deepEqual.
import assert from 'node:assert'; const obj1 = { a: { b: 1, }, }; const obj2 = { a: { b: 2, }, }; const obj3 = { a: { b: 1, }, }; const obj4 = { __proto__: obj1 }; assert.notDeepEqual(obj1, obj1); // AssertionError: { a: { b: 1 } } notDeepEqual { a: { b: 1 } } assert.notDeepEqual(obj1, obj2); // OK assert.notDeepEqual(obj1, obj3); // AssertionError: { a: { b: 1 } } notDeepEqual { a: { b: 1 } } assert.notDeepEqual(obj1, obj4); // OK
If the values are deeply equal, an
AssertionError
is thrown with amessage
property set equal to the value of themessage
parameter. If themessage
parameter is undefined, a default error message is assigned. If themessage
parameter is an instance of anError
then it will be thrown instead of theAssertionError
.actual: unknown,expected: unknown,): void;Tests for deep strict inequality. Opposite of deepStrictEqual.
import assert from 'node:assert/strict'; assert.notDeepStrictEqual({ a: 1 }, { a: '1' }); // OK
If the values are deeply and strictly equal, an
AssertionError
is thrown with amessage
property set equal to the value of themessage
parameter. If themessage
parameter is undefined, a default error message is assigned. If themessage
parameter is an instance of anError
then it will be thrown instead of theAssertionError
.actual: unknown,expected: unknown,): void;Strict assertion mode
An alias of notStrictEqual.
Legacy assertion mode
Stability: 3 - Legacy: Use notStrictEqual instead.
Tests shallow, coercive inequality with the
!=
operator.NaN
is specially handled and treated as being identical if both sides areNaN
.import assert from 'node:assert'; assert.notEqual(1, 2); // OK assert.notEqual(1, 1); // AssertionError: 1 != 1 assert.notEqual(1, '1'); // AssertionError: 1 != '1'
If the values are equal, an
AssertionError
is thrown with amessage
property set equal to the value of themessage
parameter. If themessage
parameter is undefined, a default error message is assigned. If themessage
parameter is an instance of anError
then it will be thrown instead of theAssertionError
.actual: unknown,expected: unknown,): void;Tests strict inequality between the
actual
andexpected
parameters as determined byObject.is()
.import assert from 'node:assert/strict'; assert.notStrictEqual(1, 2); // OK assert.notStrictEqual(1, 1); // AssertionError [ERR_ASSERTION]: Expected "actual" to be strictly unequal to: // // 1 assert.notStrictEqual(1, '1'); // OK
If the values are strictly equal, an
AssertionError
is thrown with amessage
property set equal to the value of themessage
parameter. If themessage
parameter is undefined, a default error message is assigned. If themessage
parameter is an instance of anError
then it will be thrown instead of theAssertionError
.value: unknown,): asserts value;Tests if
value
is truthy. It is equivalent toassert.equal(!!value, true, message)
.If
value
is not truthy, anAssertionError
is thrown with amessage
property set equal to the value of themessage
parameter. If themessage
parameter isundefined
, a default error message is assigned. If themessage
parameter is an instance of anError
then it will be thrown instead of theAssertionError
. If no arguments are passed in at allmessage
will be set to the string:'No value argument passed to `assert.ok()`'
.Be aware that in the
repl
the error message will be different to the one thrown in a file! See below for further details.import assert from 'node:assert/strict'; assert.ok(true); // OK assert.ok(1); // OK assert.ok(); // AssertionError: No value argument passed to `assert.ok()` assert.ok(false, 'it\'s false'); // AssertionError: it's false // In the repl: assert.ok(typeof 123 === 'string'); // AssertionError: false == true // In a file (e.g. test.js): assert.ok(typeof 123 === 'string'); // AssertionError: The expression evaluated to a falsy value: // // assert.ok(typeof 123 === 'string') assert.ok(false); // AssertionError: The expression evaluated to a falsy value: // // assert.ok(false) assert.ok(0); // AssertionError: The expression evaluated to a falsy value: // // assert.ok(0)
import assert from 'node:assert/strict'; // Using `assert()` works the same: assert(0); // AssertionError: The expression evaluated to a falsy value: // // assert(0)
actual: unknown,expected: unknown,): void;Tests for partial deep equality between the
actual
andexpected
parameters. "Deep" equality means that the enumerable "own" properties of child objects are recursively evaluated also by the following rules. "Partial" equality means that only properties that exist on theexpected
parameter are going to be compared.This method always passes the same test cases as
assert.deepStrictEqual()
, behaving as a super set of it.block: Promise<unknown> | () => Promise<unknown>,): Promise<void>;Awaits the
asyncFn
promise or, ifasyncFn
is a function, immediately calls the function and awaits the returned promise to complete. It will then check that the promise is rejected.If
asyncFn
is a function and it throws an error synchronously,assert.rejects()
will return a rejectedPromise
with that error. If the function does not return a promise,assert.rejects()
will return a rejectedPromise
with an ERR_INVALID_RETURN_VALUE error. In both cases the error handler is skipped.Besides the async nature to await the completion behaves identically to throws.
If specified,
error
can be aClass
,RegExp
, a validation function, an object where each property will be tested for, or an instance of error where each property will be tested for including the non-enumerablemessage
andname
properties.If specified,
message
will be the message provided by the{@link AssertionError}
if theasyncFn
fails to reject.import assert from 'node:assert/strict'; await assert.rejects( async () => { throw new TypeError('Wrong value'); }, { name: 'TypeError', message: 'Wrong value', }, );
import assert from 'node:assert/strict'; await assert.rejects( async () => { throw new TypeError('Wrong value'); }, (err) => { assert.strictEqual(err.name, 'TypeError'); assert.strictEqual(err.message, 'Wrong value'); return true; }, );
import assert from 'node:assert/strict'; assert.rejects( Promise.reject(new Error('Wrong value')), Error, ).then(() => { // ... });
error
cannot be a string. If a string is provided as the second argument, thenerror
is assumed to be omitted and the string will be used formessage
instead. This can lead to easy-to-miss mistakes. Please read the example in throws carefully if using a string as the second argument gets considered.block: Promise<unknown> | () => Promise<unknown>,): Promise<void>;Awaits the
asyncFn
promise or, ifasyncFn
is a function, immediately calls the function and awaits the returned promise to complete. It will then check that the promise is rejected.If
asyncFn
is a function and it throws an error synchronously,assert.rejects()
will return a rejectedPromise
with that error. If the function does not return a promise,assert.rejects()
will return a rejectedPromise
with an ERR_INVALID_RETURN_VALUE error. In both cases the error handler is skipped.Besides the async nature to await the completion behaves identically to throws.
If specified,
error
can be aClass
,RegExp
, a validation function, an object where each property will be tested for, or an instance of error where each property will be tested for including the non-enumerablemessage
andname
properties.If specified,
message
will be the message provided by the{@link AssertionError}
if theasyncFn
fails to reject.import assert from 'node:assert/strict'; await assert.rejects( async () => { throw new TypeError('Wrong value'); }, { name: 'TypeError', message: 'Wrong value', }, );
import assert from 'node:assert/strict'; await assert.rejects( async () => { throw new TypeError('Wrong value'); }, (err) => { assert.strictEqual(err.name, 'TypeError'); assert.strictEqual(err.message, 'Wrong value'); return true; }, );
import assert from 'node:assert/strict'; assert.rejects( Promise.reject(new Error('Wrong value')), Error, ).then(() => { // ... });
error
cannot be a string. If a string is provided as the second argument, thenerror
is assumed to be omitted and the string will be used formessage
instead. This can lead to easy-to-miss mistakes. Please read the example in throws carefully if using a string as the second argument gets considered.actual: unknown,expected: T,): asserts actual is T;Tests strict equality between the
actual
andexpected
parameters as determined byObject.is()
.import assert from 'node:assert/strict'; assert.strictEqual(1, 2); // AssertionError [ERR_ASSERTION]: Expected inputs to be strictly equal: // // 1 !== 2 assert.strictEqual(1, 1); // OK assert.strictEqual('Hello foobar', 'Hello World!'); // AssertionError [ERR_ASSERTION]: Expected inputs to be strictly equal: // + actual - expected // // + 'Hello foobar' // - 'Hello World!' // ^ const apples = 1; const oranges = 2; assert.strictEqual(apples, oranges, `apples ${apples} !== oranges ${oranges}`); // AssertionError [ERR_ASSERTION]: apples 1 !== oranges 2 assert.strictEqual(1, '1', new TypeError('Inputs are not identical')); // TypeError: Inputs are not identical
If the values are not strictly equal, an
AssertionError
is thrown with amessage
property set equal to the value of themessage
parameter. If themessage
parameter is undefined, a default error message is assigned. If themessage
parameter is an instance of anError
then it will be thrown instead of theAssertionError
.block: () => unknown,): void;Expects the function
fn
to throw an error.If specified,
error
can be aClass
,RegExp
, a validation function, a validation object where each property will be tested for strict deep equality, or an instance of error where each property will be tested for strict deep equality including the non-enumerablemessage
andname
properties. When using an object, it is also possible to use a regular expression, when validating against a string property. See below for examples.If specified,
message
will be appended to the message provided by theAssertionError
if thefn
call fails to throw or in case the error validation fails.Custom validation object/error instance:
import assert from 'node:assert/strict'; const err = new TypeError('Wrong value'); err.code = 404; err.foo = 'bar'; err.info = { nested: true, baz: 'text', }; err.reg = /abc/i; assert.throws( () => { throw err; }, { name: 'TypeError', message: 'Wrong value', info: { nested: true, baz: 'text', }, // Only properties on the validation object will be tested for. // Using nested objects requires all properties to be present. Otherwise // the validation is going to fail. }, ); // Using regular expressions to validate error properties: assert.throws( () => { throw err; }, { // The `name` and `message` properties are strings and using regular // expressions on those will match against the string. If they fail, an // error is thrown. name: /^TypeError$/, message: /Wrong/, foo: 'bar', info: { nested: true, // It is not possible to use regular expressions for nested properties! baz: 'text', }, // The `reg` property contains a regular expression and only if the // validation object contains an identical regular expression, it is going // to pass. reg: /abc/i, }, ); // Fails due to the different `message` and `name` properties: assert.throws( () => { const otherErr = new Error('Not found'); // Copy all enumerable properties from `err` to `otherErr`. for (const [key, value] of Object.entries(err)) { otherErr[key] = value; } throw otherErr; }, // The error's `message` and `name` properties will also be checked when using // an error as validation object. err, );
Validate instanceof using constructor:
import assert from 'node:assert/strict'; assert.throws( () => { throw new Error('Wrong value'); }, Error, );
Validate error message using
RegExp
:Using a regular expression runs
.toString
on the error object, and will therefore also include the error name.import assert from 'node:assert/strict'; assert.throws( () => { throw new Error('Wrong value'); }, /^Error: Wrong value$/, );
Custom error validation:
The function must return
true
to indicate all internal validations passed. It will otherwise fail with anAssertionError
.import assert from 'node:assert/strict'; assert.throws( () => { throw new Error('Wrong value'); }, (err) => { assert(err instanceof Error); assert(/value/.test(err)); // Avoid returning anything from validation functions besides `true`. // Otherwise, it's not clear what part of the validation failed. Instead, // throw an error about the specific validation that failed (as done in this // example) and add as much helpful debugging information to that error as // possible. return true; }, 'unexpected error', );
error
cannot be a string. If a string is provided as the second argument, thenerror
is assumed to be omitted and the string will be used formessage
instead. This can lead to easy-to-miss mistakes. Using the same message as the thrown error message is going to result in anERR_AMBIGUOUS_ARGUMENT
error. Please read the example below carefully if using a string as the second argument gets considered:import assert from 'node:assert/strict'; function throwingFirst() { throw new Error('First'); } function throwingSecond() { throw new Error('Second'); } function notThrowing() {} // The second argument is a string and the input function threw an Error. // The first case will not throw as it does not match for the error message // thrown by the input function! assert.throws(throwingFirst, 'Second'); // In the next example the message has no benefit over the message from the // error and since it is not clear if the user intended to actually match // against the error message, Node.js throws an `ERR_AMBIGUOUS_ARGUMENT` error. assert.throws(throwingSecond, 'Second'); // TypeError [ERR_AMBIGUOUS_ARGUMENT] // The string is only used (as message) in case the function does not throw: assert.throws(notThrowing, 'Second'); // AssertionError [ERR_ASSERTION]: Missing expected exception: Second // If it was intended to match for the error message do this instead: // It does not throw because the error messages match. assert.throws(throwingSecond, /Second$/); // If the error message does not match, an AssertionError is thrown. assert.throws(throwingFirst, /Second$/); // AssertionError [ERR_ASSERTION]
Due to the confusing error-prone notation, avoid a string as the second argument.
block: () => unknown,): void;Expects the function
fn
to throw an error.If specified,
error
can be aClass
,RegExp
, a validation function, a validation object where each property will be tested for strict deep equality, or an instance of error where each property will be tested for strict deep equality including the non-enumerablemessage
andname
properties. When using an object, it is also possible to use a regular expression, when validating against a string property. See below for examples.If specified,
message
will be appended to the message provided by theAssertionError
if thefn
call fails to throw or in case the error validation fails.Custom validation object/error instance:
import assert from 'node:assert/strict'; const err = new TypeError('Wrong value'); err.code = 404; err.foo = 'bar'; err.info = { nested: true, baz: 'text', }; err.reg = /abc/i; assert.throws( () => { throw err; }, { name: 'TypeError', message: 'Wrong value', info: { nested: true, baz: 'text', }, // Only properties on the validation object will be tested for. // Using nested objects requires all properties to be present. Otherwise // the validation is going to fail. }, ); // Using regular expressions to validate error properties: assert.throws( () => { throw err; }, { // The `name` and `message` properties are strings and using regular // expressions on those will match against the string. If they fail, an // error is thrown. name: /^TypeError$/, message: /Wrong/, foo: 'bar', info: { nested: true, // It is not possible to use regular expressions for nested properties! baz: 'text', }, // The `reg` property contains a regular expression and only if the // validation object contains an identical regular expression, it is going // to pass. reg: /abc/i, }, ); // Fails due to the different `message` and `name` properties: assert.throws( () => { const otherErr = new Error('Not found'); // Copy all enumerable properties from `err` to `otherErr`. for (const [key, value] of Object.entries(err)) { otherErr[key] = value; } throw otherErr; }, // The error's `message` and `name` properties will also be checked when using // an error as validation object. err, );
Validate instanceof using constructor:
import assert from 'node:assert/strict'; assert.throws( () => { throw new Error('Wrong value'); }, Error, );
Validate error message using
RegExp
:Using a regular expression runs
.toString
on the error object, and will therefore also include the error name.import assert from 'node:assert/strict'; assert.throws( () => { throw new Error('Wrong value'); }, /^Error: Wrong value$/, );
Custom error validation:
The function must return
true
to indicate all internal validations passed. It will otherwise fail with anAssertionError
.import assert from 'node:assert/strict'; assert.throws( () => { throw new Error('Wrong value'); }, (err) => { assert(err instanceof Error); assert(/value/.test(err)); // Avoid returning anything from validation functions besides `true`. // Otherwise, it's not clear what part of the validation failed. Instead, // throw an error about the specific validation that failed (as done in this // example) and add as much helpful debugging information to that error as // possible. return true; }, 'unexpected error', );
error
cannot be a string. If a string is provided as the second argument, thenerror
is assumed to be omitted and the string will be used formessage
instead. This can lead to easy-to-miss mistakes. Using the same message as the thrown error message is going to result in anERR_AMBIGUOUS_ARGUMENT
error. Please read the example below carefully if using a string as the second argument gets considered:import assert from 'node:assert/strict'; function throwingFirst() { throw new Error('First'); } function throwingSecond() { throw new Error('Second'); } function notThrowing() {} // The second argument is a string and the input function threw an Error. // The first case will not throw as it does not match for the error message // thrown by the input function! assert.throws(throwingFirst, 'Second'); // In the next example the message has no benefit over the message from the // error and since it is not clear if the user intended to actually match // against the error message, Node.js throws an `ERR_AMBIGUOUS_ARGUMENT` error. assert.throws(throwingSecond, 'Second'); // TypeError [ERR_AMBIGUOUS_ARGUMENT] // The string is only used (as message) in case the function does not throw: assert.throws(notThrowing, 'Second'); // AssertionError [ERR_ASSERTION]: Missing expected exception: Second // If it was intended to match for the error message do this instead: // It does not throw because the error messages match. assert.throws(throwingSecond, /Second$/); // If the error message does not match, an AssertionError is thrown. assert.throws(throwingFirst, /Second$/); // AssertionError [ERR_ASSERTION]
Due to the confusing error-prone notation, avoid a string as the second argument.