diff --git a/etc/notes/errors.md b/etc/notes/errors.md index 0d3d85d50a..9cebe037e8 100644 --- a/etc/notes/errors.md +++ b/etc/notes/errors.md @@ -111,7 +111,9 @@ This class should **never** be directly instantiated. ### `MongoOperationTimeoutError` -- TODO(NODE-6491): Add MongoOperationTimeoutError documentation +The `MongoOperationTimeoutError` class represents an error that occurs when an operation could not be completed within the specified `timeoutMS`. +It is generated by the driver in support of the "client side operation timeout" feature and inherits from `MongoDriverError`. +When `timeoutMS` is enabled `MongoServerErrors` relating to `MaxTimeExpired` errors will be converted to `MongoOperationTimeoutError`. ### MongoUnexpectedServerResponseError diff --git a/src/client-side-encryption/auto_encrypter.ts b/src/client-side-encryption/auto_encrypter.ts index e27c32123c..edf731b92a 100644 --- a/src/client-side-encryption/auto_encrypter.ts +++ b/src/client-side-encryption/auto_encrypter.ts @@ -312,7 +312,7 @@ export class AutoEncrypter { if (net.getDefaultAutoSelectFamily) { // AutoEncrypter is made inside of MongoClient constructor while options are being parsed, // we do not have access to the options that are in progress. - // TODO(NODE-NODE-6449): AutoEncrypter does not use client options for autoSelectFamily + // TODO(NODE-6449): AutoEncrypter does not use client options for autoSelectFamily Object.assign(clientOptions, autoSelectSocketOptions(this._client.s?.options ?? {})); } diff --git a/src/collection.ts b/src/collection.ts index 24469b56ef..50adfbca76 100644 --- a/src/collection.ts +++ b/src/collection.ts @@ -687,8 +687,8 @@ export class Collection { ); return true; } catch (error) { - if (error instanceof MongoOperationTimeoutError) throw error; // TODO: Check the spec for index management behaviour/file a drivers ticket for this - // Seems like we should throw all errors + // TODO(NODE-6517): Driver should only filter for namespace not found error. Other errors should be thrown. + if (error instanceof MongoOperationTimeoutError) throw error; return false; } } diff --git a/src/error.ts b/src/error.ts index c96b2e5b8d..a3ae965b78 100644 --- a/src/error.ts +++ b/src/error.ts @@ -861,7 +861,9 @@ export class MongoUnexpectedServerResponseError extends MongoRuntimeError { * @public * @category Error * - * This error is thrown when an operation could not be completed within the specified `timeoutMS`. + * The `MongoOperationTimeoutError` class represents an error that occurs when an operation could not be completed within the specified `timeoutMS`. + * It is generated by the driver in support of the "client side operation timeout" feature so inherits from `MongoDriverError`. + * When `timeoutMS` is enabled `MongoServerError`s relating to `MaxTimeExpired` errors will be converted to `MongoOperationTimeoutError` * * @example * ```ts diff --git a/src/gridfs/download.ts b/src/gridfs/download.ts index 19651b885e..022bcf9444 100644 --- a/src/gridfs/download.ts +++ b/src/gridfs/download.ts @@ -30,7 +30,10 @@ export interface GridFSBucketReadStreamOptions { * to be returned by the stream. `end` is non-inclusive */ end?: number; - /** @public */ + /** + * @experimental + * Specifies the time an operation will run until it throws a timeout error + */ timeoutMS?: number; } diff --git a/src/gridfs/upload.ts b/src/gridfs/upload.ts index ef3d25f62e..6191e457be 100644 --- a/src/gridfs/upload.ts +++ b/src/gridfs/upload.ts @@ -42,7 +42,10 @@ export interface GridFSBucketWriteStreamOptions extends WriteConcernOptions { * @deprecated Will be removed in the next major version. Add an aliases field to the metadata document instead. */ aliases?: string[]; - /** @public */ + /** + * @experimental + * Specifies the time an operation will run until it throws a timeout error + */ timeoutMS?: number; } diff --git a/src/sdam/topology.ts b/src/sdam/topology.ts index e0d55dcff3..2ea7d3244f 100644 --- a/src/sdam/topology.ts +++ b/src/sdam/topology.ts @@ -460,11 +460,10 @@ export class Topology extends TypedEventEmitter { } } - // TODO(NODE-6223): auto connect cannot use timeoutMS - // const timeoutMS = this.client.s.options.timeoutMS; const serverSelectionTimeoutMS = this.client.s.options.serverSelectionTimeoutMS; const readPreference = options.readPreference ?? ReadPreference.primary; const timeoutContext = TimeoutContext.create({ + // TODO(NODE-6448): auto-connect ignores timeoutMS; potential future feature timeoutMS: undefined, serverSelectionTimeoutMS, waitQueueTimeoutMS: this.client.s.options.waitQueueTimeoutMS diff --git a/src/sessions.ts b/src/sessions.ts index f323d1a93b..c53bc2e485 100644 --- a/src/sessions.ts +++ b/src/sessions.ts @@ -61,6 +61,7 @@ export interface ClientSessionOptions { defaultTransactionOptions?: TransactionOptions; /** * @public + * @experimental * An overriding timeoutMS value to use for a client-side timeout. * If not provided the session uses the timeoutMS specified on the MongoClient. */ diff --git a/test/integration/client-side-operations-timeout/client_side_operations_timeout.prose.test.ts b/test/integration/client-side-operations-timeout/client_side_operations_timeout.prose.test.ts index 9d2865b3e3..51bd834a20 100644 --- a/test/integration/client-side-operations-timeout/client_side_operations_timeout.prose.test.ts +++ b/test/integration/client-side-operations-timeout/client_side_operations_timeout.prose.test.ts @@ -28,7 +28,6 @@ import { import { type FailPoint, makeMultiBatchWrite, measureDuration } from '../../tools/utils'; import { filterForCommands } from '../shared'; -// TODO(NODE-5824): Implement CSOT prose tests describe('CSOT spec prose tests', function () { let internalClient: MongoClient; let client: MongoClient; diff --git a/test/integration/client-side-operations-timeout/client_side_operations_timeout.spec.test.ts b/test/integration/client-side-operations-timeout/client_side_operations_timeout.spec.test.ts index 2a8614b2dd..a1b0791026 100644 --- a/test/integration/client-side-operations-timeout/client_side_operations_timeout.spec.test.ts +++ b/test/integration/client-side-operations-timeout/client_side_operations_timeout.spec.test.ts @@ -16,7 +16,7 @@ const skippedTests = { 'maxTimeMS value in the command is less than timeoutMS': 'TODO(DRIVERS-2970): see modified test in unified-csot-node-specs', 'timeoutMS is refreshed for getMore - failure': - 'TODO(DRIVERS-2965): see modified test in unified-csot-node-specs', // Skipping for both tailable awaitData and tailable non-awaitData cursors + 'TODO(DRIVERS-2965): see modified test in unified-csot-node-specs', 'timeoutMS applies to full resume attempt in a next call': 'TODO(DRIVERS-3006)', 'timeoutMS is refreshed for getMore if maxAwaitTimeMS is set': 'TODO(DRIVERS-3018)' }; diff --git a/test/integration/client-side-operations-timeout/client_side_operations_timeout.unit.test.ts b/test/integration/client-side-operations-timeout/client_side_operations_timeout.unit.test.ts index 90b04e9a3e..58bfb79de2 100644 --- a/test/integration/client-side-operations-timeout/client_side_operations_timeout.unit.test.ts +++ b/test/integration/client-side-operations-timeout/client_side_operations_timeout.unit.test.ts @@ -25,7 +25,6 @@ import { import { measureDuration, sleep } from '../../tools/utils'; import { createTimerSandbox } from '../../unit/timer_sandbox'; -// TODO(NODE-5824): Implement CSOT prose tests describe('CSOT spec unit tests', function () { let client: MongoClient; @@ -107,7 +106,7 @@ describe('CSOT spec unit tests', function () { () => {} ); }).skipReason = - 'TODO(NODE-5682): Add CSOT support for socket read/write at the connection layer for CRUD APIs'; + 'TODO(NODE-6518): Add CSOT support for socket read/write at the connection layer for CRUD APIs'; describe('Client side encryption', function () { describe('KMS requests', function () { diff --git a/test/unit/operations/get_more.test.ts b/test/unit/operations/get_more.test.ts index 17bc20f6fa..76ebf16555 100644 --- a/test/unit/operations/get_more.test.ts +++ b/test/unit/operations/get_more.test.ts @@ -53,7 +53,12 @@ describe('GetMoreOperation', function () { new ServerDescription('a:1'), {} as any ); - const opts = { ...options, documentsReturnedIn: 'nextBatch', returnFieldSelector: null }; + const opts = { + ...options, + documentsReturnedIn: 'nextBatch', + returnFieldSelector: null, + timeoutContext: undefined + }; const operation = new GetMoreOperation(namespace, cursorId, server, opts); const stub = sinon.stub(server, 'command').resolves({}); @@ -69,7 +74,7 @@ describe('GetMoreOperation', function () { const call = stub.getCall(0); expect(call.args[0]).to.equal(namespace); expect(call.args[1]).to.deep.equal(expectedGetMoreCommand); - expect(call.args[2]).to.containSubset(opts); + expect(call.args[2]).to.deep.equal(opts); }); });