error.js 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", { value: true });
  3. exports.isResumableError = exports.isNetworkTimeoutError = exports.isSDAMUnrecoverableError = exports.isNodeShuttingDownError = exports.isRetryableReadError = exports.isRetryableWriteError = exports.needsRetryableWriteLabel = exports.MongoWriteConcernError = exports.MongoServerSelectionError = exports.MongoSystemError = exports.MongoMissingDependencyError = exports.MongoMissingCredentialsError = exports.MongoCompatibilityError = exports.MongoInvalidArgumentError = exports.MongoParseError = exports.MongoNetworkTimeoutError = exports.MongoNetworkError = exports.isNetworkErrorBeforeHandshake = exports.MongoTopologyClosedError = exports.MongoCursorExhaustedError = exports.MongoServerClosedError = exports.MongoCursorInUseError = exports.MongoUnexpectedServerResponseError = exports.MongoGridFSChunkError = exports.MongoGridFSStreamError = exports.MongoTailableCursorError = exports.MongoChangeStreamError = exports.MongoAWSError = exports.MongoKerberosError = exports.MongoExpiredSessionError = exports.MongoTransactionError = exports.MongoNotConnectedError = exports.MongoDecompressionError = exports.MongoBatchReExecutionError = exports.MongoRuntimeError = exports.MongoAPIError = exports.MongoDriverError = exports.MongoServerError = exports.MongoError = exports.MongoErrorLabel = exports.GET_MORE_RESUMABLE_CODES = exports.MONGODB_ERROR_CODES = exports.NODE_IS_RECOVERING_ERROR_MESSAGE = exports.LEGACY_NOT_PRIMARY_OR_SECONDARY_ERROR_MESSAGE = exports.LEGACY_NOT_WRITABLE_PRIMARY_ERROR_MESSAGE = void 0;
  4. /** @internal */
  5. const kErrorLabels = Symbol('errorLabels');
  6. /**
  7. * @internal
  8. * The legacy error message from the server that indicates the node is not a writable primary
  9. * https://github.com/mongodb/specifications/blob/b07c26dc40d04ac20349f989db531c9845fdd755/source/server-discovery-and-monitoring/server-discovery-and-monitoring.rst#not-writable-primary-and-node-is-recovering
  10. */
  11. exports.LEGACY_NOT_WRITABLE_PRIMARY_ERROR_MESSAGE = new RegExp('not master', 'i');
  12. /**
  13. * @internal
  14. * The legacy error message from the server that indicates the node is not a primary or secondary
  15. * https://github.com/mongodb/specifications/blob/b07c26dc40d04ac20349f989db531c9845fdd755/source/server-discovery-and-monitoring/server-discovery-and-monitoring.rst#not-writable-primary-and-node-is-recovering
  16. */
  17. exports.LEGACY_NOT_PRIMARY_OR_SECONDARY_ERROR_MESSAGE = new RegExp('not master or secondary', 'i');
  18. /**
  19. * @internal
  20. * The error message from the server that indicates the node is recovering
  21. * https://github.com/mongodb/specifications/blob/b07c26dc40d04ac20349f989db531c9845fdd755/source/server-discovery-and-monitoring/server-discovery-and-monitoring.rst#not-writable-primary-and-node-is-recovering
  22. */
  23. exports.NODE_IS_RECOVERING_ERROR_MESSAGE = new RegExp('node is recovering', 'i');
  24. /** @internal MongoDB Error Codes */
  25. exports.MONGODB_ERROR_CODES = Object.freeze({
  26. HostUnreachable: 6,
  27. HostNotFound: 7,
  28. NetworkTimeout: 89,
  29. ShutdownInProgress: 91,
  30. PrimarySteppedDown: 189,
  31. ExceededTimeLimit: 262,
  32. SocketException: 9001,
  33. NotWritablePrimary: 10107,
  34. InterruptedAtShutdown: 11600,
  35. InterruptedDueToReplStateChange: 11602,
  36. NotPrimaryNoSecondaryOk: 13435,
  37. NotPrimaryOrSecondary: 13436,
  38. StaleShardVersion: 63,
  39. StaleEpoch: 150,
  40. StaleConfig: 13388,
  41. RetryChangeStream: 234,
  42. FailedToSatisfyReadPreference: 133,
  43. CursorNotFound: 43,
  44. LegacyNotPrimary: 10058,
  45. WriteConcernFailed: 64,
  46. NamespaceNotFound: 26,
  47. IllegalOperation: 20,
  48. MaxTimeMSExpired: 50,
  49. UnknownReplWriteConcern: 79,
  50. UnsatisfiableWriteConcern: 100
  51. });
  52. // From spec@https://github.com/mongodb/specifications/blob/f93d78191f3db2898a59013a7ed5650352ef6da8/source/change-streams/change-streams.rst#resumable-error
  53. exports.GET_MORE_RESUMABLE_CODES = new Set([
  54. exports.MONGODB_ERROR_CODES.HostUnreachable,
  55. exports.MONGODB_ERROR_CODES.HostNotFound,
  56. exports.MONGODB_ERROR_CODES.NetworkTimeout,
  57. exports.MONGODB_ERROR_CODES.ShutdownInProgress,
  58. exports.MONGODB_ERROR_CODES.PrimarySteppedDown,
  59. exports.MONGODB_ERROR_CODES.ExceededTimeLimit,
  60. exports.MONGODB_ERROR_CODES.SocketException,
  61. exports.MONGODB_ERROR_CODES.NotWritablePrimary,
  62. exports.MONGODB_ERROR_CODES.InterruptedAtShutdown,
  63. exports.MONGODB_ERROR_CODES.InterruptedDueToReplStateChange,
  64. exports.MONGODB_ERROR_CODES.NotPrimaryNoSecondaryOk,
  65. exports.MONGODB_ERROR_CODES.NotPrimaryOrSecondary,
  66. exports.MONGODB_ERROR_CODES.StaleShardVersion,
  67. exports.MONGODB_ERROR_CODES.StaleEpoch,
  68. exports.MONGODB_ERROR_CODES.StaleConfig,
  69. exports.MONGODB_ERROR_CODES.RetryChangeStream,
  70. exports.MONGODB_ERROR_CODES.FailedToSatisfyReadPreference,
  71. exports.MONGODB_ERROR_CODES.CursorNotFound
  72. ]);
  73. /** @public */
  74. exports.MongoErrorLabel = Object.freeze({
  75. RetryableWriteError: 'RetryableWriteError',
  76. TransientTransactionError: 'TransientTransactionError',
  77. UnknownTransactionCommitResult: 'UnknownTransactionCommitResult',
  78. ResumableChangeStreamError: 'ResumableChangeStreamError',
  79. HandshakeError: 'HandshakeError'
  80. });
  81. /**
  82. * @public
  83. * @category Error
  84. *
  85. * @privateRemarks
  86. * CSFLE has a dependency on this error, it uses the constructor with a string argument
  87. */
  88. class MongoError extends Error {
  89. constructor(message) {
  90. if (message instanceof Error) {
  91. super(message.message);
  92. }
  93. else {
  94. super(message);
  95. }
  96. this[kErrorLabels] = new Set();
  97. }
  98. get name() {
  99. return 'MongoError';
  100. }
  101. /** Legacy name for server error responses */
  102. get errmsg() {
  103. return this.message;
  104. }
  105. /**
  106. * Checks the error to see if it has an error label
  107. *
  108. * @param label - The error label to check for
  109. * @returns returns true if the error has the provided error label
  110. */
  111. hasErrorLabel(label) {
  112. return this[kErrorLabels].has(label);
  113. }
  114. addErrorLabel(label) {
  115. this[kErrorLabels].add(label);
  116. }
  117. get errorLabels() {
  118. return Array.from(this[kErrorLabels]);
  119. }
  120. }
  121. exports.MongoError = MongoError;
  122. /**
  123. * An error coming from the mongo server
  124. *
  125. * @public
  126. * @category Error
  127. */
  128. class MongoServerError extends MongoError {
  129. constructor(message) {
  130. super(message.message || message.errmsg || message.$err || 'n/a');
  131. if (message.errorLabels) {
  132. this[kErrorLabels] = new Set(message.errorLabels);
  133. }
  134. for (const name in message) {
  135. if (name !== 'errorLabels' && name !== 'errmsg' && name !== 'message')
  136. this[name] = message[name];
  137. }
  138. }
  139. get name() {
  140. return 'MongoServerError';
  141. }
  142. }
  143. exports.MongoServerError = MongoServerError;
  144. /**
  145. * An error generated by the driver
  146. *
  147. * @public
  148. * @category Error
  149. */
  150. class MongoDriverError extends MongoError {
  151. constructor(message) {
  152. super(message);
  153. }
  154. get name() {
  155. return 'MongoDriverError';
  156. }
  157. }
  158. exports.MongoDriverError = MongoDriverError;
  159. /**
  160. * An error generated when the driver API is used incorrectly
  161. *
  162. * @privateRemarks
  163. * Should **never** be directly instantiated
  164. *
  165. * @public
  166. * @category Error
  167. */
  168. class MongoAPIError extends MongoDriverError {
  169. constructor(message) {
  170. super(message);
  171. }
  172. get name() {
  173. return 'MongoAPIError';
  174. }
  175. }
  176. exports.MongoAPIError = MongoAPIError;
  177. /**
  178. * An error generated when the driver encounters unexpected input
  179. * or reaches an unexpected/invalid internal state
  180. *
  181. * @privateRemarks
  182. * Should **never** be directly instantiated.
  183. *
  184. * @public
  185. * @category Error
  186. */
  187. class MongoRuntimeError extends MongoDriverError {
  188. constructor(message) {
  189. super(message);
  190. }
  191. get name() {
  192. return 'MongoRuntimeError';
  193. }
  194. }
  195. exports.MongoRuntimeError = MongoRuntimeError;
  196. /**
  197. * An error generated when a batch command is re-executed after one of the commands in the batch
  198. * has failed
  199. *
  200. * @public
  201. * @category Error
  202. */
  203. class MongoBatchReExecutionError extends MongoAPIError {
  204. constructor(message = 'This batch has already been executed, create new batch to execute') {
  205. super(message);
  206. }
  207. get name() {
  208. return 'MongoBatchReExecutionError';
  209. }
  210. }
  211. exports.MongoBatchReExecutionError = MongoBatchReExecutionError;
  212. /**
  213. * An error generated when the driver fails to decompress
  214. * data received from the server.
  215. *
  216. * @public
  217. * @category Error
  218. */
  219. class MongoDecompressionError extends MongoRuntimeError {
  220. constructor(message) {
  221. super(message);
  222. }
  223. get name() {
  224. return 'MongoDecompressionError';
  225. }
  226. }
  227. exports.MongoDecompressionError = MongoDecompressionError;
  228. /**
  229. * An error thrown when the user attempts to operate on a database or collection through a MongoClient
  230. * that has not yet successfully called the "connect" method
  231. *
  232. * @public
  233. * @category Error
  234. */
  235. class MongoNotConnectedError extends MongoAPIError {
  236. constructor(message) {
  237. super(message);
  238. }
  239. get name() {
  240. return 'MongoNotConnectedError';
  241. }
  242. }
  243. exports.MongoNotConnectedError = MongoNotConnectedError;
  244. /**
  245. * An error generated when the user makes a mistake in the usage of transactions.
  246. * (e.g. attempting to commit a transaction with a readPreference other than primary)
  247. *
  248. * @public
  249. * @category Error
  250. */
  251. class MongoTransactionError extends MongoAPIError {
  252. constructor(message) {
  253. super(message);
  254. }
  255. get name() {
  256. return 'MongoTransactionError';
  257. }
  258. }
  259. exports.MongoTransactionError = MongoTransactionError;
  260. /**
  261. * An error generated when the user attempts to operate
  262. * on a session that has expired or has been closed.
  263. *
  264. * @public
  265. * @category Error
  266. */
  267. class MongoExpiredSessionError extends MongoAPIError {
  268. constructor(message = 'Cannot use a session that has ended') {
  269. super(message);
  270. }
  271. get name() {
  272. return 'MongoExpiredSessionError';
  273. }
  274. }
  275. exports.MongoExpiredSessionError = MongoExpiredSessionError;
  276. /**
  277. * A error generated when the user attempts to authenticate
  278. * via Kerberos, but fails to connect to the Kerberos client.
  279. *
  280. * @public
  281. * @category Error
  282. */
  283. class MongoKerberosError extends MongoRuntimeError {
  284. constructor(message) {
  285. super(message);
  286. }
  287. get name() {
  288. return 'MongoKerberosError';
  289. }
  290. }
  291. exports.MongoKerberosError = MongoKerberosError;
  292. /**
  293. * A error generated when the user attempts to authenticate
  294. * via AWS, but fails
  295. *
  296. * @public
  297. * @category Error
  298. */
  299. class MongoAWSError extends MongoRuntimeError {
  300. constructor(message) {
  301. super(message);
  302. }
  303. get name() {
  304. return 'MongoAWSError';
  305. }
  306. }
  307. exports.MongoAWSError = MongoAWSError;
  308. /**
  309. * An error generated when a ChangeStream operation fails to execute.
  310. *
  311. * @public
  312. * @category Error
  313. */
  314. class MongoChangeStreamError extends MongoRuntimeError {
  315. constructor(message) {
  316. super(message);
  317. }
  318. get name() {
  319. return 'MongoChangeStreamError';
  320. }
  321. }
  322. exports.MongoChangeStreamError = MongoChangeStreamError;
  323. /**
  324. * An error thrown when the user calls a function or method not supported on a tailable cursor
  325. *
  326. * @public
  327. * @category Error
  328. */
  329. class MongoTailableCursorError extends MongoAPIError {
  330. constructor(message = 'Tailable cursor does not support this operation') {
  331. super(message);
  332. }
  333. get name() {
  334. return 'MongoTailableCursorError';
  335. }
  336. }
  337. exports.MongoTailableCursorError = MongoTailableCursorError;
  338. /** An error generated when a GridFSStream operation fails to execute.
  339. *
  340. * @public
  341. * @category Error
  342. */
  343. class MongoGridFSStreamError extends MongoRuntimeError {
  344. constructor(message) {
  345. super(message);
  346. }
  347. get name() {
  348. return 'MongoGridFSStreamError';
  349. }
  350. }
  351. exports.MongoGridFSStreamError = MongoGridFSStreamError;
  352. /**
  353. * An error generated when a malformed or invalid chunk is
  354. * encountered when reading from a GridFSStream.
  355. *
  356. * @public
  357. * @category Error
  358. */
  359. class MongoGridFSChunkError extends MongoRuntimeError {
  360. constructor(message) {
  361. super(message);
  362. }
  363. get name() {
  364. return 'MongoGridFSChunkError';
  365. }
  366. }
  367. exports.MongoGridFSChunkError = MongoGridFSChunkError;
  368. /**
  369. * An error generated when a **parsable** unexpected response comes from the server.
  370. * This is generally an error where the driver in a state expecting a certain behavior to occur in
  371. * the next message from MongoDB but it receives something else.
  372. * This error **does not** represent an issue with wire message formatting.
  373. *
  374. * #### Example
  375. * When an operation fails, it is the driver's job to retry it. It must perform serverSelection
  376. * again to make sure that it attempts the operation against a server in a good state. If server
  377. * selection returns a server that does not support retryable operations, this error is used.
  378. * This scenario is unlikely as retryable support would also have been determined on the first attempt
  379. * but it is possible the state change could report a selectable server that does not support retries.
  380. *
  381. * @public
  382. * @category Error
  383. */
  384. class MongoUnexpectedServerResponseError extends MongoRuntimeError {
  385. constructor(message) {
  386. super(message);
  387. }
  388. get name() {
  389. return 'MongoUnexpectedServerResponseError';
  390. }
  391. }
  392. exports.MongoUnexpectedServerResponseError = MongoUnexpectedServerResponseError;
  393. /**
  394. * An error thrown when the user attempts to add options to a cursor that has already been
  395. * initialized
  396. *
  397. * @public
  398. * @category Error
  399. */
  400. class MongoCursorInUseError extends MongoAPIError {
  401. constructor(message = 'Cursor is already initialized') {
  402. super(message);
  403. }
  404. get name() {
  405. return 'MongoCursorInUseError';
  406. }
  407. }
  408. exports.MongoCursorInUseError = MongoCursorInUseError;
  409. /**
  410. * An error generated when an attempt is made to operate
  411. * on a closed/closing server.
  412. *
  413. * @public
  414. * @category Error
  415. */
  416. class MongoServerClosedError extends MongoAPIError {
  417. constructor(message = 'Server is closed') {
  418. super(message);
  419. }
  420. get name() {
  421. return 'MongoServerClosedError';
  422. }
  423. }
  424. exports.MongoServerClosedError = MongoServerClosedError;
  425. /**
  426. * An error thrown when an attempt is made to read from a cursor that has been exhausted
  427. *
  428. * @public
  429. * @category Error
  430. */
  431. class MongoCursorExhaustedError extends MongoAPIError {
  432. constructor(message) {
  433. super(message || 'Cursor is exhausted');
  434. }
  435. get name() {
  436. return 'MongoCursorExhaustedError';
  437. }
  438. }
  439. exports.MongoCursorExhaustedError = MongoCursorExhaustedError;
  440. /**
  441. * An error generated when an attempt is made to operate on a
  442. * dropped, or otherwise unavailable, database.
  443. *
  444. * @public
  445. * @category Error
  446. */
  447. class MongoTopologyClosedError extends MongoAPIError {
  448. constructor(message = 'Topology is closed') {
  449. super(message);
  450. }
  451. get name() {
  452. return 'MongoTopologyClosedError';
  453. }
  454. }
  455. exports.MongoTopologyClosedError = MongoTopologyClosedError;
  456. /** @internal */
  457. const kBeforeHandshake = Symbol('beforeHandshake');
  458. function isNetworkErrorBeforeHandshake(err) {
  459. return err[kBeforeHandshake] === true;
  460. }
  461. exports.isNetworkErrorBeforeHandshake = isNetworkErrorBeforeHandshake;
  462. /**
  463. * An error indicating an issue with the network, including TCP errors and timeouts.
  464. * @public
  465. * @category Error
  466. */
  467. class MongoNetworkError extends MongoError {
  468. constructor(message, options) {
  469. super(message);
  470. if (options && typeof options.beforeHandshake === 'boolean') {
  471. this[kBeforeHandshake] = options.beforeHandshake;
  472. }
  473. }
  474. get name() {
  475. return 'MongoNetworkError';
  476. }
  477. }
  478. exports.MongoNetworkError = MongoNetworkError;
  479. /**
  480. * An error indicating a network timeout occurred
  481. * @public
  482. * @category Error
  483. *
  484. * @privateRemarks
  485. * CSFLE has a dependency on this error with an instanceof check
  486. */
  487. class MongoNetworkTimeoutError extends MongoNetworkError {
  488. constructor(message, options) {
  489. super(message, options);
  490. }
  491. get name() {
  492. return 'MongoNetworkTimeoutError';
  493. }
  494. }
  495. exports.MongoNetworkTimeoutError = MongoNetworkTimeoutError;
  496. /**
  497. * An error used when attempting to parse a value (like a connection string)
  498. * @public
  499. * @category Error
  500. */
  501. class MongoParseError extends MongoDriverError {
  502. constructor(message) {
  503. super(message);
  504. }
  505. get name() {
  506. return 'MongoParseError';
  507. }
  508. }
  509. exports.MongoParseError = MongoParseError;
  510. /**
  511. * An error generated when the user supplies malformed or unexpected arguments
  512. * or when a required argument or field is not provided.
  513. *
  514. *
  515. * @public
  516. * @category Error
  517. */
  518. class MongoInvalidArgumentError extends MongoAPIError {
  519. constructor(message) {
  520. super(message);
  521. }
  522. get name() {
  523. return 'MongoInvalidArgumentError';
  524. }
  525. }
  526. exports.MongoInvalidArgumentError = MongoInvalidArgumentError;
  527. /**
  528. * An error generated when a feature that is not enabled or allowed for the current server
  529. * configuration is used
  530. *
  531. *
  532. * @public
  533. * @category Error
  534. */
  535. class MongoCompatibilityError extends MongoAPIError {
  536. constructor(message) {
  537. super(message);
  538. }
  539. get name() {
  540. return 'MongoCompatibilityError';
  541. }
  542. }
  543. exports.MongoCompatibilityError = MongoCompatibilityError;
  544. /**
  545. * An error generated when the user fails to provide authentication credentials before attempting
  546. * to connect to a mongo server instance.
  547. *
  548. *
  549. * @public
  550. * @category Error
  551. */
  552. class MongoMissingCredentialsError extends MongoAPIError {
  553. constructor(message) {
  554. super(message);
  555. }
  556. get name() {
  557. return 'MongoMissingCredentialsError';
  558. }
  559. }
  560. exports.MongoMissingCredentialsError = MongoMissingCredentialsError;
  561. /**
  562. * An error generated when a required module or dependency is not present in the local environment
  563. *
  564. * @public
  565. * @category Error
  566. */
  567. class MongoMissingDependencyError extends MongoAPIError {
  568. constructor(message) {
  569. super(message);
  570. }
  571. get name() {
  572. return 'MongoMissingDependencyError';
  573. }
  574. }
  575. exports.MongoMissingDependencyError = MongoMissingDependencyError;
  576. /**
  577. * An error signifying a general system issue
  578. * @public
  579. * @category Error
  580. */
  581. class MongoSystemError extends MongoError {
  582. constructor(message, reason) {
  583. var _a;
  584. if (reason && reason.error) {
  585. super(reason.error.message || reason.error);
  586. }
  587. else {
  588. super(message);
  589. }
  590. if (reason) {
  591. this.reason = reason;
  592. }
  593. this.code = (_a = reason.error) === null || _a === void 0 ? void 0 : _a.code;
  594. }
  595. get name() {
  596. return 'MongoSystemError';
  597. }
  598. }
  599. exports.MongoSystemError = MongoSystemError;
  600. /**
  601. * An error signifying a client-side server selection error
  602. * @public
  603. * @category Error
  604. */
  605. class MongoServerSelectionError extends MongoSystemError {
  606. constructor(message, reason) {
  607. super(message, reason);
  608. }
  609. get name() {
  610. return 'MongoServerSelectionError';
  611. }
  612. }
  613. exports.MongoServerSelectionError = MongoServerSelectionError;
  614. function makeWriteConcernResultObject(input) {
  615. const output = Object.assign({}, input);
  616. if (output.ok === 0) {
  617. output.ok = 1;
  618. delete output.errmsg;
  619. delete output.code;
  620. delete output.codeName;
  621. }
  622. return output;
  623. }
  624. /**
  625. * An error thrown when the server reports a writeConcernError
  626. * @public
  627. * @category Error
  628. */
  629. class MongoWriteConcernError extends MongoServerError {
  630. constructor(message, result) {
  631. if (result && Array.isArray(result.errorLabels)) {
  632. message.errorLabels = result.errorLabels;
  633. }
  634. super(message);
  635. this.errInfo = message.errInfo;
  636. if (result != null) {
  637. this.result = makeWriteConcernResultObject(result);
  638. }
  639. }
  640. get name() {
  641. return 'MongoWriteConcernError';
  642. }
  643. }
  644. exports.MongoWriteConcernError = MongoWriteConcernError;
  645. // https://github.com/mongodb/specifications/blob/master/source/retryable-reads/retryable-reads.rst#retryable-error
  646. const RETRYABLE_READ_ERROR_CODES = new Set([
  647. exports.MONGODB_ERROR_CODES.HostUnreachable,
  648. exports.MONGODB_ERROR_CODES.HostNotFound,
  649. exports.MONGODB_ERROR_CODES.NetworkTimeout,
  650. exports.MONGODB_ERROR_CODES.ShutdownInProgress,
  651. exports.MONGODB_ERROR_CODES.PrimarySteppedDown,
  652. exports.MONGODB_ERROR_CODES.SocketException,
  653. exports.MONGODB_ERROR_CODES.NotWritablePrimary,
  654. exports.MONGODB_ERROR_CODES.InterruptedAtShutdown,
  655. exports.MONGODB_ERROR_CODES.InterruptedDueToReplStateChange,
  656. exports.MONGODB_ERROR_CODES.NotPrimaryNoSecondaryOk,
  657. exports.MONGODB_ERROR_CODES.NotPrimaryOrSecondary
  658. ]);
  659. // see: https://github.com/mongodb/specifications/blob/master/source/retryable-writes/retryable-writes.rst#terms
  660. const RETRYABLE_WRITE_ERROR_CODES = new Set([
  661. ...RETRYABLE_READ_ERROR_CODES,
  662. exports.MONGODB_ERROR_CODES.ExceededTimeLimit
  663. ]);
  664. function needsRetryableWriteLabel(error, maxWireVersion) {
  665. var _a, _b, _c;
  666. // pre-4.4 server, then the driver adds an error label for every valid case
  667. // execute operation will only inspect the label, code/message logic is handled here
  668. if (error instanceof MongoNetworkError) {
  669. return true;
  670. }
  671. if (error instanceof MongoError) {
  672. if ((maxWireVersion >= 9 || error.hasErrorLabel(exports.MongoErrorLabel.RetryableWriteError)) &&
  673. !error.hasErrorLabel(exports.MongoErrorLabel.HandshakeError)) {
  674. // If we already have the error label no need to add it again. 4.4+ servers add the label.
  675. // In the case where we have a handshake error, need to fall down to the logic checking
  676. // the codes.
  677. return false;
  678. }
  679. }
  680. if (error instanceof MongoWriteConcernError) {
  681. return RETRYABLE_WRITE_ERROR_CODES.has((_c = (_b = (_a = error.result) === null || _a === void 0 ? void 0 : _a.code) !== null && _b !== void 0 ? _b : error.code) !== null && _c !== void 0 ? _c : 0);
  682. }
  683. if (error instanceof MongoError && typeof error.code === 'number') {
  684. return RETRYABLE_WRITE_ERROR_CODES.has(error.code);
  685. }
  686. const isNotWritablePrimaryError = exports.LEGACY_NOT_WRITABLE_PRIMARY_ERROR_MESSAGE.test(error.message);
  687. if (isNotWritablePrimaryError) {
  688. return true;
  689. }
  690. const isNodeIsRecoveringError = exports.NODE_IS_RECOVERING_ERROR_MESSAGE.test(error.message);
  691. if (isNodeIsRecoveringError) {
  692. return true;
  693. }
  694. return false;
  695. }
  696. exports.needsRetryableWriteLabel = needsRetryableWriteLabel;
  697. function isRetryableWriteError(error) {
  698. return error.hasErrorLabel(exports.MongoErrorLabel.RetryableWriteError);
  699. }
  700. exports.isRetryableWriteError = isRetryableWriteError;
  701. /** Determines whether an error is something the driver should attempt to retry */
  702. function isRetryableReadError(error) {
  703. const hasRetryableErrorCode = typeof error.code === 'number' ? RETRYABLE_READ_ERROR_CODES.has(error.code) : false;
  704. if (hasRetryableErrorCode) {
  705. return true;
  706. }
  707. if (error instanceof MongoNetworkError) {
  708. return true;
  709. }
  710. const isNotWritablePrimaryError = exports.LEGACY_NOT_WRITABLE_PRIMARY_ERROR_MESSAGE.test(error.message);
  711. if (isNotWritablePrimaryError) {
  712. return true;
  713. }
  714. const isNodeIsRecoveringError = exports.NODE_IS_RECOVERING_ERROR_MESSAGE.test(error.message);
  715. if (isNodeIsRecoveringError) {
  716. return true;
  717. }
  718. return false;
  719. }
  720. exports.isRetryableReadError = isRetryableReadError;
  721. const SDAM_RECOVERING_CODES = new Set([
  722. exports.MONGODB_ERROR_CODES.ShutdownInProgress,
  723. exports.MONGODB_ERROR_CODES.PrimarySteppedDown,
  724. exports.MONGODB_ERROR_CODES.InterruptedAtShutdown,
  725. exports.MONGODB_ERROR_CODES.InterruptedDueToReplStateChange,
  726. exports.MONGODB_ERROR_CODES.NotPrimaryOrSecondary
  727. ]);
  728. const SDAM_NOT_PRIMARY_CODES = new Set([
  729. exports.MONGODB_ERROR_CODES.NotWritablePrimary,
  730. exports.MONGODB_ERROR_CODES.NotPrimaryNoSecondaryOk,
  731. exports.MONGODB_ERROR_CODES.LegacyNotPrimary
  732. ]);
  733. const SDAM_NODE_SHUTTING_DOWN_ERROR_CODES = new Set([
  734. exports.MONGODB_ERROR_CODES.InterruptedAtShutdown,
  735. exports.MONGODB_ERROR_CODES.ShutdownInProgress
  736. ]);
  737. function isRecoveringError(err) {
  738. if (typeof err.code === 'number') {
  739. // If any error code exists, we ignore the error.message
  740. return SDAM_RECOVERING_CODES.has(err.code);
  741. }
  742. return (exports.LEGACY_NOT_PRIMARY_OR_SECONDARY_ERROR_MESSAGE.test(err.message) ||
  743. exports.NODE_IS_RECOVERING_ERROR_MESSAGE.test(err.message));
  744. }
  745. function isNotWritablePrimaryError(err) {
  746. if (typeof err.code === 'number') {
  747. // If any error code exists, we ignore the error.message
  748. return SDAM_NOT_PRIMARY_CODES.has(err.code);
  749. }
  750. if (isRecoveringError(err)) {
  751. return false;
  752. }
  753. return exports.LEGACY_NOT_WRITABLE_PRIMARY_ERROR_MESSAGE.test(err.message);
  754. }
  755. function isNodeShuttingDownError(err) {
  756. return !!(typeof err.code === 'number' && SDAM_NODE_SHUTTING_DOWN_ERROR_CODES.has(err.code));
  757. }
  758. exports.isNodeShuttingDownError = isNodeShuttingDownError;
  759. /**
  760. * Determines whether SDAM can recover from a given error. If it cannot
  761. * then the pool will be cleared, and server state will completely reset
  762. * locally.
  763. *
  764. * @see https://github.com/mongodb/specifications/blob/master/source/server-discovery-and-monitoring/server-discovery-and-monitoring.rst#not-master-and-node-is-recovering
  765. */
  766. function isSDAMUnrecoverableError(error) {
  767. // NOTE: null check is here for a strictly pre-CMAP world, a timeout or
  768. // close event are considered unrecoverable
  769. if (error instanceof MongoParseError || error == null) {
  770. return true;
  771. }
  772. return isRecoveringError(error) || isNotWritablePrimaryError(error);
  773. }
  774. exports.isSDAMUnrecoverableError = isSDAMUnrecoverableError;
  775. function isNetworkTimeoutError(err) {
  776. return !!(err instanceof MongoNetworkError && err.message.match(/timed out/));
  777. }
  778. exports.isNetworkTimeoutError = isNetworkTimeoutError;
  779. function isResumableError(error, wireVersion) {
  780. if (error == null || !(error instanceof MongoError)) {
  781. return false;
  782. }
  783. if (error instanceof MongoNetworkError) {
  784. return true;
  785. }
  786. if (wireVersion != null && wireVersion >= 9) {
  787. // DRIVERS-1308: For 4.4 drivers running against 4.4 servers, drivers will add a special case to treat the CursorNotFound error code as resumable
  788. if (error.code === exports.MONGODB_ERROR_CODES.CursorNotFound) {
  789. return true;
  790. }
  791. return error.hasErrorLabel(exports.MongoErrorLabel.ResumableChangeStreamError);
  792. }
  793. if (typeof error.code === 'number') {
  794. return exports.GET_MORE_RESUMABLE_CODES.has(error.code);
  795. }
  796. return false;
  797. }
  798. exports.isResumableError = isResumableError;
  799. //# sourceMappingURL=error.js.map