Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion src/collection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -493,7 +493,10 @@ export class Collection<TSchema extends Document = Document> {
filter: Filter<TSchema> = {},
options: FindOptions = {}
): Promise<WithId<TSchema> | null> {
return this.find(filter, options).limit(-1).batchSize(1).next();
const cursor = this.find(filter, options).limit(-1).batchSize(1);
const res = await cursor.next();
await cursor.close();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Calling close without try/finally here I believe is correct, a cursor that receives an error always calls close. Also, calling close unconditionally makes sense because close already includes the logic to no-op when the cursor has already been closed.

return res;
}

/**
Expand Down
19 changes: 17 additions & 2 deletions test/integration/crud/crud_api.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,14 @@
import { expect } from 'chai';
import { on } from 'events';

import { type MongoClient, MongoError, ObjectId, ReturnDocument } from '../../mongodb';
import * as sinon from 'sinon';

import {
AbstractCursor,
type MongoClient,
MongoError,
ObjectId,
ReturnDocument
} from '../../mongodb';
import { assert as test } from '../shared';

// instanceof cannot be use reliably to detect the new models in js due to scoping and new
Expand Down Expand Up @@ -31,6 +38,8 @@ describe('CRUD API', function () {
});

afterEach(async function () {
sinon.restore();

await client?.close();
client = null;

Expand Down Expand Up @@ -61,6 +70,12 @@ describe('CRUD API', function () {
await client.close();
});

it('findOne calls cursor.close()', async function () {
const spy = sinon.spy(AbstractCursor.prototype, 'close');
await client.db().collection('t').findOne({});
expect(spy).to.be.calledOnce;
});

context('when creating a cursor with find', () => {
let collection;

Expand Down