22
33const {
44 DateNow,
5- ErrorIsError ,
5+ Error ,
66 JSONStringify,
77 ObjectAssign,
88 ObjectKeys,
9+ ObjectPrototypeToString,
910 SafeSet,
1011} = primordials ;
1112
@@ -129,21 +130,32 @@ class JSONConsumer extends LogConsumer {
129130 }
130131
131132 _createStream ( stream ) {
133+ // Fast path: already a Utf8Stream
132134 if ( stream instanceof Utf8Stream ) {
133135 return stream ;
134136 }
135137
138+ // Number: file descriptor
136139 if ( typeof stream === 'number' ) {
137140 return new Utf8Stream ( { fd : stream } ) ;
138141 }
139142
143+ // String: file path
140144 if ( typeof stream === 'string' ) {
141145 return new Utf8Stream ( { dest : stream } ) ;
142146 }
143147
144- throw new ERR_INVALID_ARG_TYPE ( 'options.stream' ,
145- [ 'number' , 'string' , 'Utf8Stream' ] ,
146- stream ) ;
148+ // Object: custom stream with write method
149+ if ( typeof stream === 'object' && stream !== null &&
150+ typeof stream . write === 'function' ) {
151+ return stream ;
152+ }
153+
154+ throw new ERR_INVALID_ARG_TYPE (
155+ 'options.stream' ,
156+ [ 'number' , 'string' , 'Utf8Stream' , 'object with write method' ] ,
157+ stream ,
158+ ) ;
147159 }
148160
149161 handle ( record ) {
@@ -189,15 +201,15 @@ class JSONConsumer extends LogConsumer {
189201class Logger {
190202 constructor ( options = kEmptyObject ) {
191203 validateObject ( options , 'options' ) ;
192- const {
193- level = 'info' ,
194- bindings = kEmptyObject ,
195- } = options ;
204+ const { level = 'info' , bindings = kEmptyObject } = options ;
196205
197206 validateString ( level , 'options.level' ) ;
198207 if ( ! LEVELS [ level ] ) {
199- throw new ERR_INVALID_ARG_VALUE ( 'options.level' , level ,
200- `must be one of: ${ LEVEL_NAMES . join ( ', ' ) } ` ) ;
208+ throw new ERR_INVALID_ARG_VALUE (
209+ 'options.level' ,
210+ level ,
211+ `must be one of: ${ LEVEL_NAMES . join ( ', ' ) } ` ,
212+ ) ;
201213 }
202214
203215 validateObject ( bindings , 'options.bindings' ) ;
@@ -206,7 +218,6 @@ class Logger {
206218 this . _levelValue = LEVELS [ level ] ;
207219 this . _bindings = bindings ;
208220
209- // Optimize: replace disabled log methods with noop
210221 this . _setLogMethods ( ) ;
211222 }
212223
@@ -263,7 +274,13 @@ class Logger {
263274 * @private
264275 */
265276 _isError ( value ) {
266- return ErrorIsError ( value ) ;
277+ // TODO(@mertcanaltin): Use ErrorIsError from primordials when available
278+ // For now, use manual check until ErrorIsError is added to primordials
279+
280+ return value !== null &&
281+ typeof value === 'object' &&
282+ ( ObjectPrototypeToString ( value ) === '[object Error]' ||
283+ value instanceof Error ) ;
267284 }
268285
269286 /**
@@ -303,7 +320,7 @@ class Logger {
303320 } ;
304321 } else if ( typeof msgOrObj === 'string' ) {
305322 msg = msgOrObj ;
306- logFields = fields || kEmptyObject ;
323+ logFields = fields ?? kEmptyObject ;
307324 } else {
308325 const { msg : extractedMsg , ...restFields } = msgOrObj ;
309326 msg = extractedMsg ;
@@ -312,6 +329,10 @@ class Logger {
312329 if ( logFields . err && this . _isError ( logFields . err ) ) {
313330 logFields . err = this . _serializeError ( logFields . err ) ;
314331 }
332+
333+ if ( logFields . error && this . _isError ( logFields . error ) ) {
334+ logFields . error = this . _serializeError ( logFields . error ) ;
335+ }
315336 }
316337
317338 const record = {
0 commit comments