diff --git a/docs/charts/README.md b/docs/charts/README.md new file mode 100644 index 00000000000..f2598110661 --- /dev/null +++ b/docs/charts/README.md @@ -0,0 +1,7 @@ +# Charts and mermaid code + +The `mermaid` directory contains the [mermaid](https://mermaid-js.github.io/mermaid/#/) files which serve as the source code for the svg files included in the `../errors.md` + +To generate these files, there is an included script, `build_images.sh` which builds images for all the mermaid files in the `mermaid` directory. + +To use this script, the [mermaid cli](https://github.com/mermaid-js/mermaid-cli) must be installed and be accessible via your $PATH variable. diff --git a/docs/charts/build_images.sh b/docs/charts/build_images.sh new file mode 100755 index 00000000000..4a9a34f7dcf --- /dev/null +++ b/docs/charts/build_images.sh @@ -0,0 +1,13 @@ +#! /bin/bash + +echo "Building svgs..." +cd mermaid +for f in *.mmd +do + echo "Processing $f" + outname="${f%%.*}" + mmdc -i $f -o ../imgs/$outname.svg & +done +wait + +echo "Done" diff --git a/docs/charts/imgs/MongoAPIError.svg b/docs/charts/imgs/MongoAPIError.svg new file mode 100644 index 00000000000..9d46d069617 --- /dev/null +++ b/docs/charts/imgs/MongoAPIError.svg @@ -0,0 +1,4 @@ +
MongoAPIError
MongoInvalidArgumentError
MongoCompatibilityError
MongoMissingCredentialsError
MongoMissingDependencyError
\ No newline at end of file diff --git a/docs/charts/imgs/MongoError.svg b/docs/charts/imgs/MongoError.svg new file mode 100644 index 00000000000..41f37b7adb0 --- /dev/null +++ b/docs/charts/imgs/MongoError.svg @@ -0,0 +1,4 @@ +
MongoError
MongoDriverError
MongoNetworkError
MongoServerError
MongoSystemError
MongoAPIError
MongoRuntimeError
\ No newline at end of file diff --git a/docs/charts/imgs/MongoRuntimeError_0.svg b/docs/charts/imgs/MongoRuntimeError_0.svg new file mode 100644 index 00000000000..6a0961223a3 --- /dev/null +++ b/docs/charts/imgs/MongoRuntimeError_0.svg @@ -0,0 +1,4 @@ +
MongoRuntimeError
MongoBatchReExecutionError
MongoCursorError
MongoInvalidClassInstantiationError
MongoNotConnectedError
MongoTailableCursorError
MongoCursorInUseError
MongoCursorExhaustedError
\ No newline at end of file diff --git a/docs/charts/imgs/MongoRuntimeError_1.svg b/docs/charts/imgs/MongoRuntimeError_1.svg new file mode 100644 index 00000000000..41dd25f7a6a --- /dev/null +++ b/docs/charts/imgs/MongoRuntimeError_1.svg @@ -0,0 +1,4 @@ +
MongoRuntimeError
MongoURIError
MongoServerSelectionError
MongoStreamError
MongoCompressionError
MongoDecompressionError
MongoChangeStreamError
MongoGridFSStreamError
MongoGridFSChunkError
\ No newline at end of file diff --git a/docs/charts/imgs/MongoRuntimeError_2.svg b/docs/charts/imgs/MongoRuntimeError_2.svg new file mode 100644 index 00000000000..7d796039bcc --- /dev/null +++ b/docs/charts/imgs/MongoRuntimeError_2.svg @@ -0,0 +1,4 @@ +
MongoRuntimeError
MongoTransactionError
MongoExpiredSessionError
MongoKerberosError
MongoResourceClosedError
MongoServerClosedError
MongoStreamClosedError
MongoTopologyClosedError
\ No newline at end of file diff --git a/docs/charts/mermaid/MongoAPIError.mmd b/docs/charts/mermaid/MongoAPIError.mmd new file mode 100644 index 00000000000..7275b04dc46 --- /dev/null +++ b/docs/charts/mermaid/MongoAPIError.mmd @@ -0,0 +1,5 @@ +graph TD + MongoAPIError --> MongoInvalidArgumentError + MongoAPIError --> MongoCompatibilityError + MongoAPIError --> MongoMissingCredentialsError + MongoAPIError --> MongoMissingDependencyError diff --git a/docs/charts/mermaid/MongoError.mmd b/docs/charts/mermaid/MongoError.mmd new file mode 100644 index 00000000000..5ed6b9fe5fb --- /dev/null +++ b/docs/charts/mermaid/MongoError.mmd @@ -0,0 +1,8 @@ +graph TD + MongoError --> MongoDriverError + MongoError --> MongoNetworkError + MongoError --> MongoServerError + MongoError --> MongoSystemError + MongoDriverError --> MongoAPIError + MongoDriverError --> MongoRuntimeError + diff --git a/docs/charts/mermaid/MongoRuntimeError_0.mmd b/docs/charts/mermaid/MongoRuntimeError_0.mmd new file mode 100644 index 00000000000..2646b76d906 --- /dev/null +++ b/docs/charts/mermaid/MongoRuntimeError_0.mmd @@ -0,0 +1,9 @@ +graph TD + MongoRuntimeError --> MongoBatchReExecutionError + MongoRuntimeError --> MongoCursorError + MongoRuntimeError --> MongoInvalidClassInstantiationError + MongoRuntimeError --> MongoNotConnectedError + + MongoCursorError --> MongoTailableCursorError + MongoCursorError --> MongoCursorInUseError + MongoCursorError --> MongoCursorExhaustedError diff --git a/docs/charts/mermaid/MongoRuntimeError_1.mmd b/docs/charts/mermaid/MongoRuntimeError_1.mmd new file mode 100644 index 00000000000..7dfd97740ac --- /dev/null +++ b/docs/charts/mermaid/MongoRuntimeError_1.mmd @@ -0,0 +1,10 @@ +graph TD + MongoRuntimeError --> MongoURIError + MongoRuntimeError --> MongoServerSelectionError + MongoRuntimeError --> MongoStreamError + MongoRuntimeError --> MongoCompressionError + MongoRuntimeError --> MongoDecompressionError + + MongoStreamError --> MongoChangeStreamError + MongoStreamError --> MongoGridFSStreamError + MongoStreamError --> MongoGridFSChunkError diff --git a/docs/charts/mermaid/MongoRuntimeError_2.mmd b/docs/charts/mermaid/MongoRuntimeError_2.mmd new file mode 100644 index 00000000000..632d3326916 --- /dev/null +++ b/docs/charts/mermaid/MongoRuntimeError_2.mmd @@ -0,0 +1,9 @@ +graph TD + MongoRuntimeError --> MongoTransactionError + MongoRuntimeError --> MongoExpiredSessionError + MongoRuntimeError --> MongoKerberosError + MongoRuntimeError --> MongoResourceClosedError + + MongoResourceClosedError --> MongoServerClosedError + MongoResourceClosedError --> MongoStreamClosedError + MongoResourceClosedError --> MongoTopologyClosedError diff --git a/docs/errors.md b/docs/errors.md new file mode 100644 index 00000000000..f008c365651 --- /dev/null +++ b/docs/errors.md @@ -0,0 +1,225 @@ +# Error Class Hierarchy + +**Title**: Error Class Hierarchy + +**Authors**: Warren James, Andy Mina + +**Advisory Group**: Daria Purdue, Eric Adum, Neal Beeken + +### Contents + +- [Introduction](#Introduction) +- [Errors](#errors) + - [`MongoError`](#MongoError) + - [`MongoDriverError`](#MongoDriverError) + - [`MongoAPIError`](#MongoAPIError) + - [`MongoRuntimeError`](#MongoRuntimeError) + - [`MongoNetworkError`](#MongoNetworkError) + - [`MongoServerError`](#MongoServerError) + - [`MongoSystemError`](#MongoSystemError) +- [Test Plan](#Test-Plan) + - [`MongoAPIError`](#MongoAPIError-1) + - [`MongoInvalidArgumentError`](#MongoInvalidArgumentError-1) + - [`MongoMissingCredentialsError`](#MongoMissingCredentialsError-1) + - [`MongoRuntimeError`](#MongoRuntimeError-1) + - [`MongoNotConnectedError`](#MongoNotConnectedError-1) + - [`MongoServerClosedError`](#MongoServerClosedError-1) + - [`MongoStreamClosedError`](#MongoStreamClosedError-1) + - [`MongoTopologyClosedError`](#MongoTopologyClosedError-1) + - [`MongoCursorExhaustedError`](#MongoCursorExhaustedError-1) + - [`MongoNetworkError`](#MongoNetworkError-1) + - [`MongoNetworkTimeoutError`](#MongoNetworkTimeoutError-1) + +# Errors + +All errors are derived from the `MongoError` class which should **never** be instantiated. +There are four main error classes which stem from `MongoError`: `MongoDriverError`, `MongoNetworkError`, `MongoServerError`, and `MongoSystemError`. + +## `MongoError` + +The base class from which all errors in the Node driver subclass. +`MongoError` should **never** be be directly instantiated. +![(MongoError hierarchy tree)](charts/imgs/MongoError.svg) + +Children of `MongoError` include: + +- [`MongoDriverError`](#MongoDriverError) +- [`MongoNetworkError`](#MongoNetworkError) +- [`MongoServerError`](#MongoServerError) +- [`MongoSystemError`](#MongoSystemError) + +## `MongoDriverError` + +This class represents errors which originate in the driver itself or in the user's use of the driver. +This class should **never** be directly instantiated. +Its children are the main classes of errors that most users will interact with: [**`MongoAPIError`**](#MongoAPIError) and [**`MongoRuntimeError`**](#MongoRuntimeError). + +### `MongoAPIError` + +This class represents errors which originate from misuse of the driver API and will generally be thrown before making contact with the server. +This class should **never** be directly instantiated. +![(MongoAPIError hierarchy tree)](charts/imgs/MongoAPIError.svg) +Children of `MongoAPIError` include: + +- #### `MongoInvalidArgumentError` + + - Thrown when the user supplies malformed, unexpected arguments or failed to provide a required argument or field. + +- #### `MongoCompatibilityError` + + - Thrown when a feature that is not enabled or allowed for the current server configuration is used. + +- #### `MongoMissingCredentialsError` + + - Thrown when a user fails to provide authentication credentials before attempting to connect to the mongo server. + +- #### `MongoMissingDependencyError` + - Thrown when a required module or dependency is not present. + +### `MongoRuntimeError` + +This class represents errors which occur when the driver encounters unexpected input or reaches an unexpected/invalid internal state. +This class should **never** be directly instantiated. + +_MongoRuntimeError children (pt 1)_ +![(MongoRuntimeError hierarchy tree part 1)](charts/imgs/MongoRuntimeError_0.svg) + +_MongoRuntimeError children (pt 2)_ +![(MongoRuntimeError hierarchy tree part 2)](charts/imgs/MongoRuntimeError_1.svg) + +_MongoRuntimeError children (pt 3)_ +![(MongoRuntimeError hierarchy tree part 3)](charts/imgs/MongoRuntimeError_2.svg) + +Children of `MongoRuntimeError` include: + +- #### `MongoTransactionError` + + - Thrown when the user makes a mistake in the usage of transactions (e.g.: attempting to commit a transaction with a readPreference other than primary). + +- #### `MongoNotConnectedError` + + - Thrown when the user attempts to operate on the data from a client that has not been connected to a MongoDB server instance. + +- #### `MongoKerberosError` + + - Thrown when the user attempts to authenticate via Kerberos, but fails to connect to the Kerberos client. + +- #### `MongoCompressionError` + + - Thrown when the driver fails to compress data before sending it to the server. + +- #### `MongoDecompressionError` + + - Thrown when the driver fails to decompress data received from the server + +- #### `MongoExpiredSessionError` + + - Thrown when the user attempts to operate on a session that has expired or has been closed. + +- #### `MongoURIError` + + - Thrown when a user supplies an incorrect URI to the driver. + +- #### `MongoResourceClosedError` + + - Thrown when there is an attempt to access a resource which has already been or will be closed/destroyed. + - Children of this error class include: + - **`MongoServerClosedError`**: Thrown when an attempt is made to operate on a closed server. + - **`MongoStreamClosedError`**: Thrown when an attempt is made to operate on a closed stream. + - **`MongoTopologyClosedError`**: Thrown when an attempt is made to operate on a dropped, or otherwise unavailable, database. + +- #### `MongoCursorError` + + - Thrown when the user incorrectly uses a cursor object. + - Children of this error class include: + - **`MongoTailableCursorError`**: Thrown when the user calls a function or method that is not supported on a tailable cursor. + - **`MongoCursorInUseError`**: Thrown when the user attempts to add options to an already initialized cursor. + - **`MongoCursorExhaustedError`**: Thrown when an attempt is made to read from a cursor that has been exhausted. + +- #### `MongoStreamError` + + - Thrown when a stream operation fails to execute. + - Children of this error class include: + - **`MongoChangeStreamError`**: Thrown when an error is encountered when operating on a ChangeStream. + - **`MongoGridFSStreamError`**: Thrown when an unexpected state is reached when operating on a GridFSStream. + - **`MongoGridFSChunkError`**: Thrown when a malformed or invalid chunk is encountered when reading from a GridFSStream. + +- #### `MongoBatchReExecutionError` + + - Thrown when a user attempts to reexecute a batch command when one of the constituent commands has failed. + +- #### `MongoServerSelectionError` + + - Thrown when the driver fails to select a server to complete an operation. + +## `MongoNetworkError` + +These are errors which prevent the driver from connecting to a mongo server instance. Children of this class include: + +- #### `MongoNetworkTimeoutError` + + - Thrown when a timeout expires while attempting to connect to the mongo server + +## `MongoServerError` + +These are errors which wrap error responses received from the server. + +## `MongoSystemError` + +These are errors which originate from faulty environment setup. + +# Test Plan + +The test plan consists of a series of prose tests. +As numerous errors are being introduced, select classes will be tested. +The classes to be tested will be selected based on two characteristics: + +1. The **frequency** with which users may encounter this error. Errors that users will likely run into, including but not limited to `MongoInvalidArgumentError` and `MongoNetworkTimeoutError`, are a part of the test plan. _Note:_ Error classes that should never be instantiated, such as `MongoAPIError` and `MongoRuntimeError`, will not be tested as the user should not encounter them. +2. The **scope** of the error. Errors that tackle a large subset of issues, including but not limited to `MongoServerError` and `MongoSystemError`, will _not_ be a part of the test plan. +3. The **existing coverage** of the error. Errors that are already covered in existing tests will _not_ be a part of the test plan to avoid redundancy. + +## `MongoAPIError` + +#### `MongoInvalidArgumentError` + +- Create a `MongoClient` object and supply a number in place of the connection string when calling `.connect()` + - Assert that `MongoInvalidArgumentError` is thrown. + +#### `MongoMissingCredentialsError` + +- Fail to provide credentials when authenticating with the x509 mechanism. + - Assert that `MongoMissingCredentialsError` is thrown. + +## `MongoRuntimeError` + +#### `MongoNotConnectedError` + +- Attempt to access a database without establishing a connection to a MongoDB server. + - Assert that `MongoNotConnectedError` is thrown. + +#### `MongoServerClosedError` + +- Attempt to execute a query against a server that has closed. + - Assert that `MongoServerClosedError` is thrown. + +#### `MongoStreamClosedError` + +- Attempt to execute `tryNext()` on a `ChangeStream` object that is closed. + - Assert that `MongoStreamClosedError` is thrown. + +#### `MongoTopologyClosedError` + +- Attempt to execute `createCollection()` against a database that has been closed. + - Assert that `MongoTopologyClosedError` is thrown. + +#### `MongoCursorExhaustedError` + +- Attempt to continue reading a cursor after it has reached the end of the batch. + - Assert that `MongoCursorExhaustedError` is thrown. + +## `MongoNetworkError` + +#### `MongoNetworkTimeoutError` + +- Create a `MongoClient` object and set the `connectTimeoutMS` option to 1. + - Assert that a `MongoNetworkTimeoutError` is thrown. diff --git a/test/functional/gridfs_stream.test.js b/test/functional/gridfs_stream.test.js index ad96aa63620..e6f9a1f528c 100644 --- a/test/functional/gridfs_stream.test.js +++ b/test/functional/gridfs_stream.test.js @@ -95,6 +95,38 @@ describe('GridFS Stream', function () { } }); + it('destroy publishes provided error', { + metadata: { requires: { topology: ['single'] } }, + test: function (done) { + var configuration = this.configuration; + + var client = configuration.newClient(configuration.writeConcernMax(), { maxPoolSize: 1 }); + + client.connect(function (err, client) { + var db = client.db(configuration.db); + db.dropDatabase(function (error) { + expect(error).to.not.exist; + + var bucket = new GridFSBucket(db); + var readStream = fs.createReadStream('./LICENSE.md'); + var uploadStream = bucket.openUploadStream('test.dat'); + var errorMessage = 'error'; + + uploadStream.once('error', function (e) { + expect(e).to.equal(errorMessage); + client.close(done); + }); + + uploadStream.once('finish', function () { + uploadStream.destroy(errorMessage); + }); + + readStream.pipe(uploadStream); + }); + }); + } + }); + /** * Correctly stream a file from disk into GridFS using openUploadStream *