Skip to content

Commit a9c0de8

Browse files
authored
refactor(NODE-3421): replace MongoDriverError instances with MongoRuntimeError children (#2910)
* refactor: Replace MongoDriverError instances * refactor: Use MongoCursorInUseError * refactor: Change error message * refactor: Change message for MongoBatchReExecutionError instance * refactor: Give default error message to special-case error classes * test: Fix test failure related to error message * style: condense constructors * chore: remove unused import * fix: Update error class parents to better reflect when user is at fault * refactor: Remove MongoResourseClosedError * test: change to be an instanceof check
1 parent b42a1b4 commit a9c0de8

File tree

7 files changed

+69
-124
lines changed

7 files changed

+69
-124
lines changed

src/bulk/common.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ import {
55
AnyError,
66
MONGODB_ERROR_CODES,
77
MongoServerError,
8-
MongoDriverError,
9-
MongoInvalidArgumentError
8+
MongoInvalidArgumentError,
9+
MongoBatchReExecutionError
1010
} from '../error';
1111
import {
1212
applyRetryableWrites,
@@ -1181,7 +1181,7 @@ export abstract class BulkOperationBase {
11811181
options = options ?? {};
11821182

11831183
if (this.s.executed) {
1184-
return handleEarlyError(new MongoDriverError('Batch cannot be re-executed'), callback);
1184+
return handleEarlyError(new MongoBatchReExecutionError(), callback);
11851185
}
11861186

11871187
const writeConcern = WriteConcern.fromOptions(options);

src/cursor/abstract_cursor.ts

+11-5
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,13 @@
11
import { Callback, maybePromise, MongoDBNamespace, ns } from '../utils';
22
import { Long, Document, BSONSerializeOptions, pluckBSONSerializeOptions } from '../bson';
33
import { ClientSession } from '../sessions';
4-
import { MongoDriverError, MongoInvalidArgumentError } from '../error';
4+
import {
5+
MongoDriverError,
6+
MongoInvalidArgumentError,
7+
MongoCursorExhaustedError,
8+
MongoTailableCursorError,
9+
MongoCursorInUseError
10+
} from '../error';
511
import { ReadPreference, ReadPreferenceLike } from '../read_preference';
612
import type { Server } from '../sdam/server';
713
import type { Topology } from '../sdam/topology';
@@ -287,7 +293,7 @@ export abstract class AbstractCursor<
287293
next<T = TSchema>(callback?: Callback<T | null>): Promise<T | null> | void {
288294
return maybePromise(callback, done => {
289295
if (this[kId] === Long.ZERO) {
290-
return done(new MongoDriverError('Cursor is exhausted'));
296+
return done(new MongoCursorExhaustedError());
291297
}
292298

293299
next(this, true, done);
@@ -302,7 +308,7 @@ export abstract class AbstractCursor<
302308
tryNext<T = TSchema>(callback?: Callback<T | null>): Promise<T | null> | void {
303309
return maybePromise(callback, done => {
304310
if (this[kId] === Long.ZERO) {
305-
return done(new MongoDriverError('Cursor is exhausted'));
311+
return done(new MongoCursorExhaustedError());
306312
}
307313

308314
next(this, false, done);
@@ -564,7 +570,7 @@ export abstract class AbstractCursor<
564570
batchSize(value: number): this {
565571
assertUninitialized(this);
566572
if (this[kOptions].tailable) {
567-
throw new MongoDriverError('Tailable cursors do not support batchSize');
573+
throw new MongoTailableCursorError('Tailable cursor does not support batchSize');
568574
}
569575

570576
if (typeof value !== 'number') {
@@ -777,7 +783,7 @@ function cleanupCursor(cursor: AbstractCursor, callback: Callback): void {
777783
/** @internal */
778784
export function assertUninitialized(cursor: AbstractCursor): void {
779785
if (cursor[kInitialized]) {
780-
throw new MongoDriverError('Cursor is already initialized');
786+
throw new MongoCursorInUseError();
781787
}
782788
}
783789

src/cursor/find_cursor.ts

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import type { Document } from '../bson';
2-
import { MongoDriverError, MongoInvalidArgumentError } from '../error';
2+
import { MongoInvalidArgumentError, MongoTailableCursorError } from '../error';
33
import type { ExplainVerbosityLike } from '../explain';
44
import { CountOperation, CountOptions } from '../operations/count';
55
import { executeOperation, ExecutionResult } from '../operations/execute_operation';
@@ -371,7 +371,7 @@ export class FindCursor<TSchema = Document> extends AbstractCursor<TSchema> {
371371
sort(sort: Sort | string, direction?: SortDirection): this {
372372
assertUninitialized(this);
373373
if (this[kBuiltOptions].tailable) {
374-
throw new MongoDriverError('Tailable cursor does not support sorting');
374+
throw new MongoTailableCursorError('Tailable cursor does not support sorting');
375375
}
376376

377377
this[kBuiltOptions].sort = formatSort(sort, direction);
@@ -412,7 +412,7 @@ export class FindCursor<TSchema = Document> extends AbstractCursor<TSchema> {
412412
limit(value: number): this {
413413
assertUninitialized(this);
414414
if (this[kBuiltOptions].tailable) {
415-
throw new MongoDriverError('Tailable cursor does not support limit');
415+
throw new MongoTailableCursorError('Tailable cursor does not support limit');
416416
}
417417

418418
if (typeof value !== 'number') {
@@ -431,7 +431,7 @@ export class FindCursor<TSchema = Document> extends AbstractCursor<TSchema> {
431431
skip(value: number): this {
432432
assertUninitialized(this);
433433
if (this[kBuiltOptions].tailable) {
434-
throw new MongoDriverError('Tailable cursor does not support skip');
434+
throw new MongoTailableCursorError('Tailable cursor does not support skip');
435435
}
436436

437437
if (typeof value !== 'number') {

src/error.ts

+40-107
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,26 @@ export class MongoDriverError extends MongoError {
178178
}
179179
}
180180

181+
/**
182+
* An error generated when the driver API is used incorrectly
183+
*
184+
* @privateRemarks
185+
* Should **never** be directly instantiated
186+
*
187+
* @public
188+
* @category Error
189+
*/
190+
191+
export class MongoAPIError extends MongoDriverError {
192+
protected constructor(message: string) {
193+
super(message);
194+
}
195+
196+
get name(): string {
197+
return 'MongoAPIError';
198+
}
199+
}
200+
181201
/**
182202
* An error generated when the driver encounters unexpected input
183203
* or reaches an unexpected/invalid internal state
@@ -205,9 +225,9 @@ export class MongoRuntimeError extends MongoDriverError {
205225
* @public
206226
* @category Error
207227
*/
208-
export class MongoBatchReExecutionError extends MongoRuntimeError {
209-
constructor(message: string) {
210-
super(message);
228+
export class MongoBatchReExecutionError extends MongoAPIError {
229+
constructor(message?: string) {
230+
super(message || 'This batch has already been executed, create new batch to execute');
211231
}
212232

213233
get name(): string {
@@ -272,7 +292,7 @@ export class MongoDecompressionError extends MongoRuntimeError {
272292
* @public
273293
* @category Error
274294
*/
275-
export class MongoNotConnectedError extends MongoRuntimeError {
295+
export class MongoNotConnectedError extends MongoAPIError {
276296
constructor(message: string) {
277297
super(message);
278298
}
@@ -289,7 +309,7 @@ export class MongoNotConnectedError extends MongoRuntimeError {
289309
* @public
290310
* @category Error
291311
*/
292-
export class MongoTransactionError extends MongoRuntimeError {
312+
export class MongoTransactionError extends MongoAPIError {
293313
constructor(message: string) {
294314
super(message);
295315
}
@@ -306,7 +326,7 @@ export class MongoTransactionError extends MongoRuntimeError {
306326
* @public
307327
* @category Error
308328
*/
309-
export class MongoExpiredSessionError extends MongoRuntimeError {
329+
export class MongoExpiredSessionError extends MongoAPIError {
310330
constructor(message: string) {
311331
super(message);
312332
}
@@ -333,46 +353,13 @@ export class MongoKerberosError extends MongoRuntimeError {
333353
}
334354
}
335355

336-
/**
337-
* An error thrown when the user attempts to operate on a cursor that is in a state which does not
338-
* support the attempted operation.
339-
*
340-
* @public
341-
* @category Error
342-
*/
343-
export class MongoCursorError extends MongoRuntimeError {
344-
constructor(message: string) {
345-
super(message);
346-
}
347-
348-
get name(): string {
349-
return 'MongoCursorError';
350-
}
351-
}
352-
353-
/**
354-
* An error generated when a stream operation fails to execute.
355-
*
356-
* @public
357-
* @category Error
358-
*/
359-
export class MongoStreamError extends MongoRuntimeError {
360-
constructor(message: string) {
361-
super(message);
362-
}
363-
364-
get name(): string {
365-
return 'MongoStreamError';
366-
}
367-
}
368-
369356
/**
370357
* An error generated when a ChangeStream operation fails to execute.
371358
*
372359
* @public
373360
* @category Error
374361
*/
375-
export class MongoChangeStreamError extends MongoStreamError {
362+
export class MongoChangeStreamError extends MongoRuntimeError {
376363
constructor(message: string) {
377364
super(message);
378365
}
@@ -388,9 +375,9 @@ export class MongoChangeStreamError extends MongoStreamError {
388375
* @public
389376
* @category Error
390377
*/
391-
export class MongoTailableCursorError extends MongoCursorError {
392-
constructor(message: string) {
393-
super(message);
378+
export class MongoTailableCursorError extends MongoAPIError {
379+
constructor(message?: string) {
380+
super(message || 'Tailable cursor does not support this operation');
394381
}
395382

396383
get name(): string {
@@ -403,7 +390,7 @@ export class MongoTailableCursorError extends MongoCursorError {
403390
* @public
404391
* @category Error
405392
*/
406-
export class MongoGridFSStreamError extends MongoStreamError {
393+
export class MongoGridFSStreamError extends MongoRuntimeError {
407394
constructor(message: string) {
408395
super(message);
409396
}
@@ -420,7 +407,7 @@ export class MongoGridFSStreamError extends MongoStreamError {
420407
* @public
421408
* @category Error
422409
*/
423-
export class MongoGridFSChunkError extends MongoStreamError {
410+
export class MongoGridFSChunkError extends MongoRuntimeError {
424411
constructor(message: string) {
425412
super(message);
426413
}
@@ -437,41 +424,24 @@ export class MongoGridFSChunkError extends MongoStreamError {
437424
* @public
438425
* @category Error
439426
*/
440-
export class MongoCursorInUseError extends MongoCursorError {
441-
constructor(message: string) {
442-
super(message);
427+
export class MongoCursorInUseError extends MongoAPIError {
428+
constructor(message?: string) {
429+
super(message || 'Cursor is already initialized');
443430
}
444431

445432
get name(): string {
446433
return 'MongoCursorInUseError';
447434
}
448435
}
449436

450-
/**
451-
* An error generated when an attempt is made to access a resource
452-
* which has already been or will be closed/destroyed.
453-
*
454-
* @public
455-
* @category Error
456-
*/
457-
export class MongoResourceClosedError extends MongoRuntimeError {
458-
constructor(message: string) {
459-
super(message);
460-
}
461-
462-
get name(): string {
463-
return 'MongoResourceClosedError';
464-
}
465-
}
466-
467437
/**
468438
* An error generated when an attempt is made to operate
469439
* on a closed/closing server.
470440
*
471441
* @public
472442
* @category Error
473443
*/
474-
export class MongoServerClosedError extends MongoResourceClosedError {
444+
export class MongoServerClosedError extends MongoAPIError {
475445
constructor(message: string) {
476446
super(message);
477447
}
@@ -487,41 +457,24 @@ export class MongoServerClosedError extends MongoResourceClosedError {
487457
* @public
488458
* @category Error
489459
*/
490-
export class MongoCursorExhaustedError extends MongoCursorError {
491-
constructor(message: string) {
492-
super(message);
460+
export class MongoCursorExhaustedError extends MongoAPIError {
461+
constructor(message?: string) {
462+
super(message || 'Cursor is exhausted');
493463
}
494464

495465
get name(): string {
496466
return 'MongoCursorExhaustedError';
497467
}
498468
}
499469

500-
/**
501-
* An error generated when an attempt is made to operate
502-
* on a closed/closing stream.
503-
*
504-
* @public
505-
* @category Error
506-
*/
507-
export class MongoStreamClosedError extends MongoResourceClosedError {
508-
constructor(message: string) {
509-
super(message);
510-
}
511-
512-
get name(): string {
513-
return 'MongoStreamClosedError';
514-
}
515-
}
516-
517470
/**
518471
* An error generated when an attempt is made to operate on a
519472
* dropped, or otherwise unavailable, database.
520473
*
521474
* @public
522475
* @category Error
523476
*/
524-
export class MongoTopologyClosedError extends MongoResourceClosedError {
477+
export class MongoTopologyClosedError extends MongoAPIError {
525478
constructor(message: string) {
526479
super(message);
527480
}
@@ -598,26 +551,6 @@ export class MongoParseError extends MongoDriverError {
598551
}
599552
}
600553

601-
/**
602-
* An error generated when the driver API is used incorrectly
603-
*
604-
* @privateRemarks
605-
* Should **never** be directly instantiated
606-
*
607-
* @public
608-
* @category Error
609-
*/
610-
611-
export class MongoAPIError extends MongoDriverError {
612-
protected constructor(message: string) {
613-
super(message);
614-
}
615-
616-
get name(): string {
617-
return 'MongoAPIError';
618-
}
619-
}
620-
621554
/**
622555
* An error generated when the user supplies malformed or unexpected arguments
623556
* or when a required argument or field is not provided.

src/mongo_client.ts

+7-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,12 @@
11
import { Db, DbOptions } from './db';
22
import { ChangeStream, ChangeStreamOptions } from './change_stream';
33
import type { ReadPreference, ReadPreferenceMode } from './read_preference';
4-
import { AnyError, MongoDriverError, MongoInvalidArgumentError } from './error';
4+
import {
5+
AnyError,
6+
MongoDriverError,
7+
MongoInvalidArgumentError,
8+
MongoNotConnectedError
9+
} from './error';
510
import type { W, WriteConcern } from './write_concern';
611
import {
712
maybePromise,
@@ -521,7 +526,7 @@ export class MongoClient extends TypedEventEmitter<MongoClientEvents> {
521526
startSession(options?: ClientSessionOptions): ClientSession {
522527
options = Object.assign({ explicit: true }, options);
523528
if (!this.topology) {
524-
throw new MongoDriverError('Must connect to a server before calling this method');
529+
throw new MongoNotConnectedError('MongoClient must be connected to start a session');
525530
}
526531

527532
return this.topology.startSession(options, this.s.options);

0 commit comments

Comments
 (0)