mirror of
https://github.com/danny-avila/LibreChat.git
synced 2026-05-13 16:07:30 +00:00
🧹 fix: Preserve Unconsumed Primitive Splat Args in Debug Traversal
The previous round dropped every primitive SPLAT[0] value to avoid
duplicating consumed %s args, but that removed useful context from
calls like \`logger.debug('prefix:', detail)\` where the primitive was
never interpolated — users lost the \`detail\` value.
Refine the heuristic: skip a primitive splat value only when it already
appears inside the (post-interpolation) \`info.message\`; otherwise
surface it. Arrays and objects continue to surface unconditionally.
Regression test covers the 'prefix:', detail case.
Reviewed-by: Codex (P2 finding on PR #12737, commit 6bf9548f).
This commit is contained in:
parent
6bf9548ff2
commit
c29c18e8a1
2 changed files with 34 additions and 8 deletions
|
|
@ -256,6 +256,17 @@ describe('debugTraverse', () => {
|
|||
expect(tenantMatches.length).toBe(1);
|
||||
});
|
||||
|
||||
it('surfaces unconsumed primitive SPLAT[0] (no %s in message) for debug level', () => {
|
||||
const info = {
|
||||
level: 'debug',
|
||||
message: 'prefix:',
|
||||
timestamp: 'ts',
|
||||
[SPLAT_SYMBOL]: ['detailValueXYZ'],
|
||||
};
|
||||
const out = runFormatter(info);
|
||||
expect(out).toContain('detailValueXYZ');
|
||||
});
|
||||
|
||||
it('still surfaces array metadata in SPLAT[0] when no object is extracted', () => {
|
||||
const info = {
|
||||
level: 'debug',
|
||||
|
|
|
|||
|
|
@ -198,17 +198,32 @@ const debugTraverse = winston.format.printf(({ level, message, timestamp, ...met
|
|||
|
||||
/*
|
||||
* Prefer the structured metadata object (which winston merges into info)
|
||||
* over `SPLAT_SYMBOL[0]`. The first splat entry may be a *consumed*
|
||||
* printf arg — e.g. `logger.warn('failed for %s', tenant)` leaves
|
||||
* `tenant` in `SPLAT[0]` after interpolation, and appending it again
|
||||
* would emit `failed for tenant tenant`. Only fall back to the splat
|
||||
* entry when it's a non-primitive (array or plain object); a string
|
||||
* or number there is almost certainly a consumed %s/%d arg.
|
||||
* over `SPLAT_SYMBOL[0]`. For primitive splat values, skip only if the
|
||||
* value already appears in the interpolated message (i.e. `%s`/`%d`
|
||||
* consumed it) — `logger.warn('failed for %s', tenant)` leaves `tenant`
|
||||
* in `SPLAT[0]` after interpolation and would otherwise be appended a
|
||||
* second time. Unconsumed primitives like
|
||||
* `logger.debug('prefix:', detail)` still surface.
|
||||
*/
|
||||
const extracted = extractMetaObject(metadata);
|
||||
const splatFirst = metadata[SPLAT_SYMBOL]?.[0];
|
||||
const splatUsable =
|
||||
Array.isArray(splatFirst) || (splatFirst != null && typeof splatFirst === 'object');
|
||||
const splatUsable = (() => {
|
||||
if (splatFirst == null) {
|
||||
return false;
|
||||
}
|
||||
if (Array.isArray(splatFirst) || typeof splatFirst === 'object') {
|
||||
return true;
|
||||
}
|
||||
if (
|
||||
typeof splatFirst === 'string' ||
|
||||
typeof splatFirst === 'number' ||
|
||||
typeof splatFirst === 'boolean'
|
||||
) {
|
||||
const splatStr = String(splatFirst);
|
||||
return splatStr !== '' && !message.includes(splatStr);
|
||||
}
|
||||
return false;
|
||||
})();
|
||||
const debugValue = extracted ?? (splatUsable ? splatFirst : undefined);
|
||||
|
||||
if (!debugValue) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue