Skip to content

Commit

Permalink
feat: add errorKey option (#1507)
Browse files Browse the repository at this point in the history
  • Loading branch information
qwelias committed Aug 4, 2022
1 parent 42dde2a commit b288da5
Show file tree
Hide file tree
Showing 7 changed files with 54 additions and 10 deletions.
16 changes: 15 additions & 1 deletion docs/api.md
Expand Up @@ -381,6 +381,7 @@ matching the exact key of a serializer will be serialized using the defined seri
The serializers are applied when a property in the logged object matches a property
in the serializers. The only exception is the `err` serializer as it is also applied in case
the object is an instance of `Error`, e.g. `logger.info(new Error('kaboom'))`.
See `errorKey` option to change `err` namespace.

* See [pino.stdSerializers](#pino-stdserializers)

Expand Down Expand Up @@ -434,6 +435,13 @@ Default: `'msg'`

The string key for the 'message' in the JSON object.

<a id=opt-messagekey></a>
#### `errorKey` (String)

Default: `'err'`

The string key for the 'error' in the JSON object.

<a id=opt-nestedkey></a>
#### `nestedKey` (String)

Expand Down Expand Up @@ -603,6 +611,9 @@ logger.info({MIX: {IN: true}})
If the object is of type Error, it is wrapped in an object containing a property err (`{ err: mergingObject }`).
This allows for a unified error handling flow.
Options `serializers` and `errorKey` could be used at instantiation time to change the namespace
from `err` to another string as preferred.
<a id="message"></a>
#### `message` (String)
Expand All @@ -625,7 +636,7 @@ See [Avoid Message Conflict](/docs/help.md#avoid-message-conflict) for informati
on how to overcome this limitation.
If no `message` parameter is provided, and the `mergingObject` is of type `Error` or it has a property named `err`, the
`message` parameter is set to the `message` value of the error.
`message` parameter is set to the `message` value of the error. See option `errorKey` if you want to change the namespace.
The `messageKey` option can be used at instantiation time to change the namespace
from `msg` to another string as preferred.
Expand Down Expand Up @@ -689,6 +700,9 @@ const logger = pino(pinoOptions)
Errors can be supplied as either the first parameter or if already using `mergingObject` then as the `err` property on the `mergingObject`.
Options `serializers` and `errorKey` could be used at instantiation time to change the namespace
from `err` to another string as preferred.
> ## Note
> This section describes the default configuration. The error serializer can be
> mapped to a different key using the [`serializers`](#opt-serializers) option.
Expand Down
8 changes: 5 additions & 3 deletions lib/proto.js
Expand Up @@ -19,6 +19,7 @@ const {
streamSym,
serializersSym,
formattersSym,
errorKeySym,
useOnlyCustomLevelsSym,
needsMetadataGsym,
redactFmtSym,
Expand Down Expand Up @@ -174,20 +175,21 @@ function defaultMixinMergeStrategy (mergeObject, mixinObject) {
function write (_obj, msg, num) {
const t = this[timeSym]()
const mixin = this[mixinSym]
const errorKey = this[errorKeySym]
const mixinMergeStrategy = this[mixinMergeStrategySym] || defaultMixinMergeStrategy
let obj

if (_obj === undefined || _obj === null) {
obj = {}
} else if (_obj instanceof Error) {
obj = { err: _obj }
obj = { [errorKey]: _obj }
if (msg === undefined) {
msg = _obj.message
}
} else {
obj = _obj
if (msg === undefined && _obj.err) {
msg = _obj.err.message
if (msg === undefined && _obj[errorKey]) {
msg = _obj[errorKey].message
}
}

Expand Down
2 changes: 2 additions & 0 deletions lib/symbols.js
Expand Up @@ -23,6 +23,7 @@ const stringifiersSym = Symbol('pino.stringifiers')
const endSym = Symbol('pino.end')
const formatOptsSym = Symbol('pino.formatOpts')
const messageKeySym = Symbol('pino.messageKey')
const errorKeySym = Symbol('pino.errorKey')
const nestedKeySym = Symbol('pino.nestedKey')
const nestedKeyStrSym = Symbol('pino.nestedKeyStr')
const mixinMergeStrategySym = Symbol('pino.mixinMergeStrategy')
Expand Down Expand Up @@ -57,6 +58,7 @@ module.exports = {
endSym,
formatOptsSym,
messageKeySym,
errorKeySym,
nestedKeySym,
wildcardFirstSym,
needsMetadataGsym,
Expand Down
5 changes: 5 additions & 0 deletions pino.d.ts
Expand Up @@ -375,6 +375,10 @@ declare namespace pino {
* The string key for the 'message' in the JSON object. Default: "msg".
*/
messageKey?: string;
/**
* The string key for the 'error' in the JSON object. Default: "err".
*/
errorKey?: string;
/**
* The string key to place any logged object under.
*/
Expand Down Expand Up @@ -682,6 +686,7 @@ declare namespace pino {
readonly endSym: unique symbol;
readonly formatOptsSym: unique symbol;
readonly messageKeySym: unique symbol;
readonly errorKeySym: unique symbol;
readonly nestedKeySym: unique symbol;
readonly wildcardFirstSym: unique symbol;
readonly needsMetadataGsym: unique symbol;
Expand Down
4 changes: 4 additions & 0 deletions pino.js
Expand Up @@ -33,6 +33,7 @@ const {
endSym,
formatOptsSym,
messageKeySym,
errorKeySym,
nestedKeySym,
mixinSym,
useOnlyCustomLevelsSym,
Expand All @@ -49,6 +50,7 @@ const defaultOptions = {
level: 'info',
levels,
messageKey: 'msg',
errorKey: 'err',
nestedKey: null,
enabled: true,
base: { pid, hostname },
Expand Down Expand Up @@ -88,6 +90,7 @@ function pino (...args) {
serializers,
timestamp,
messageKey,
errorKey,
nestedKey,
base,
name,
Expand Down Expand Up @@ -162,6 +165,7 @@ function pino (...args) {
[endSym]: end,
[formatOptsSym]: formatOpts,
[messageKeySym]: messageKey,
[errorKeySym]: errorKey,
[nestedKeySym]: nestedKey,
// protect against injection
[nestedKeyStrSym]: nestedKey ? `,${JSON.stringify(nestedKey)}:{` : '',
Expand Down
20 changes: 20 additions & 0 deletions test/errorKey.test.js
@@ -0,0 +1,20 @@
'use strict'
const { test } = require('tap')
const { sink, once } = require('./helper')
const stdSerializers = require('pino-std-serializers')
const pino = require('../')

test('set the errorKey with error serializer', async ({ equal, same }) => {
const stream = sink()
const errorKey = 'error'
const instance = pino({
errorKey,
serializers: { [errorKey]: stdSerializers.err }
}, stream)
instance.error(new ReferenceError('test'))
const o = await once(stream, 'data')
equal(typeof o[errorKey], 'object')
equal(o[errorKey].type, 'ReferenceError')
equal(o[errorKey].message, 'test')
equal(typeof o[errorKey].stack, 'string')
})
9 changes: 3 additions & 6 deletions test/transport/core.test.js
Expand Up @@ -395,12 +395,9 @@ test('stdout in worker', async ({ not }) => {
let actual = ''
const child = execa(process.argv[0], [join(__dirname, '..', 'fixtures', 'transport-main.js')])

child.stdout.pipe(writer((s, enc, cb) => {
actual += s
cb()
}))
await once(child, 'close')
await immediate()
for await (const chunk of child.stdout) {
actual += chunk
}
not(strip(actual).match(/Hello/), null)
})

Expand Down

0 comments on commit b288da5

Please sign in to comment.