Skip to content

Commit 8f7bb59

Browse files
feat(NODE-4847): Add config error handling to logging (#3970)
Co-authored-by: Alena Khineika <[email protected]>
1 parent 38fb2e4 commit 8f7bb59

File tree

4 files changed

+300
-86
lines changed

4 files changed

+300
-86
lines changed

Diff for: src/connection_string.ts

+46-3
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,11 @@ import {
2323
ServerApiVersion
2424
} from './mongo_client';
2525
import {
26+
MongoLoggableComponent,
2627
MongoLogger,
2728
type MongoLoggerEnvOptions,
28-
type MongoLoggerMongoClientOptions
29+
type MongoLoggerMongoClientOptions,
30+
SeverityLevel
2931
} from './mongo_logger';
3032
import { ReadConcern, type ReadConcernLevel } from './read_concern';
3133
import { ReadPreference, type ReadPreferenceMode } from './read_preference';
@@ -1246,12 +1248,53 @@ export const OPTIONS = {
12461248
* @internal
12471249
* TODO: NODE-5671 - remove internal flag
12481250
*/
1249-
mongodbLogPath: { type: 'any' },
1251+
mongodbLogPath: {
1252+
transform({ values: [value] }) {
1253+
if (
1254+
!(
1255+
(typeof value === 'string' && ['stderr', 'stdout'].includes(value)) ||
1256+
(value &&
1257+
typeof value === 'object' &&
1258+
'write' in value &&
1259+
typeof value.write === 'function')
1260+
)
1261+
) {
1262+
throw new MongoAPIError(
1263+
`Option 'mongodbLogPath' must be of type 'stderr' | 'stdout' | MongoDBLogWritable`
1264+
);
1265+
}
1266+
return value;
1267+
}
1268+
},
12501269
/**
12511270
* @internal
12521271
* TODO: NODE-5671 - remove internal flag
12531272
*/
1254-
mongodbLogComponentSeverities: { type: 'any' },
1273+
mongodbLogComponentSeverities: {
1274+
transform({ values: [value] }) {
1275+
if (typeof value !== 'object' || !value) {
1276+
throw new MongoAPIError(`Option 'mongodbLogComponentSeverities' must be a non-null object`);
1277+
}
1278+
for (const [k, v] of Object.entries(value)) {
1279+
if (typeof v !== 'string' || typeof k !== 'string') {
1280+
throw new MongoAPIError(
1281+
`User input for option 'mongodbLogComponentSeverities' object cannot include a non-string key or value`
1282+
);
1283+
}
1284+
if (!Object.values(MongoLoggableComponent).some(val => val === k) && k !== 'default') {
1285+
throw new MongoAPIError(
1286+
`User input for option 'mongodbLogComponentSeverities' contains invalid key: ${k}`
1287+
);
1288+
}
1289+
if (!Object.values(SeverityLevel).some(val => val === v)) {
1290+
throw new MongoAPIError(
1291+
`Option 'mongodbLogComponentSeverities' does not support ${v} as a value for ${k}`
1292+
);
1293+
}
1294+
}
1295+
return value;
1296+
}
1297+
},
12551298
/**
12561299
* @internal
12571300
* TODO: NODE-5671 - remove internal flag

Diff for: src/mongo_logger.ts

+4-1
Original file line numberDiff line numberDiff line change
@@ -281,7 +281,10 @@ export interface Log extends Record<string, any> {
281281
message?: string;
282282
}
283283

284-
/** @internal */
284+
/**
285+
* @internal
286+
* TODO: NODE-5671 - remove internal flag and add API comments
287+
*/
285288
export interface MongoDBLogWritable {
286289
write(log: Log): PromiseLike<unknown> | unknown;
287290
}

Diff for: test/unit/connection_string.test.ts

+5-7
Original file line numberDiff line numberDiff line change
@@ -912,13 +912,11 @@ describe('Connection String', function () {
912912
});
913913

914914
context('when option is invalid', function () {
915-
it('it defaults to stderr', function () {
916-
const client = new MongoClient('mongodb://a/?mongodbLogPath=stdnothing', {
917-
[loggerFeatureFlag]: true
918-
});
919-
const log: Log = { t: new Date(), c: 'ConnectionStringInvalidOption', s: 'error' };
920-
client.options.mongoLoggerOptions.logDestination.write(log);
921-
expect(stderrStub.write).calledWith(inspect(log, { breakLength: Infinity, compact: true }));
915+
it('should throw error at construction', function () {
916+
expect(
917+
() =>
918+
new MongoClient('mongodb://a/?mongodbLogPath=stdnothing', { [loggerFeatureFlag]: true })
919+
).to.throw(MongoAPIError);
922920
});
923921
});
924922
});

0 commit comments

Comments
 (0)