Skip to content

Commit

Permalink
fix: Handle console.log of null values in React Devtools
Browse files Browse the repository at this point in the history
In some cases (can't reproduce it reliably though), turning on debug logs
and logging console.log('%s', null) will throw an error.

Falling back to the flattened message if the overloaded console.log fails.

Closes #808.
  • Loading branch information
franky47 committed Feb 12, 2025
1 parent b764322 commit 42a2bee
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 5 deletions.
36 changes: 32 additions & 4 deletions packages/nuqs/src/debug.test.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { describe, expect, test } from 'vitest'
import { describe, expect, it } from 'vitest'
import { sprintf } from './debug'

describe('debug/sprintf', () => {
test('%s', () => {
it('formats strings with %s', () => {
expect(sprintf('%s', 'foo')).toBe('foo')
expect(sprintf('%s', 1)).toBe('1')
expect(sprintf('%s', true)).toBe('true')
Expand All @@ -11,7 +11,31 @@ describe('debug/sprintf', () => {
expect(sprintf('%s', {})).toBe('[object Object]')
expect(sprintf('%s', [])).toBe('')
})
test('%O', () => {
it('formats integers with %d', () => {
expect(sprintf('%d', 1)).toBe('1')
expect(sprintf('%d', 1.5)).toBe('1.5')
expect(sprintf('%d', '1')).toBe('1')
expect(sprintf('%d', '1.5')).toBe('1.5')
expect(sprintf('%d', true)).toBe('true')
expect(sprintf('%d', false)).toBe('false')
expect(sprintf('%d', null)).toBe('null')
expect(sprintf('%d', undefined)).toBe('undefined')
expect(sprintf('%d', {})).toBe('[object Object]')
expect(sprintf('%d', [])).toBe('')
})
it('formats floats with %f', () => {
expect(sprintf('%f', 1)).toBe('1')
expect(sprintf('%f', 1.5)).toBe('1.5')
expect(sprintf('%f', '1')).toBe('1')
expect(sprintf('%f', '1.5')).toBe('1.5')
expect(sprintf('%f', true)).toBe('true')
expect(sprintf('%f', false)).toBe('false')
expect(sprintf('%f', null)).toBe('null')
expect(sprintf('%f', undefined)).toBe('undefined')
expect(sprintf('%f', {})).toBe('[object Object]')
expect(sprintf('%f', [])).toBe('')
})
it('formats objects with %O', () => {
expect(sprintf('%O', 'foo')).toBe('"foo"')
expect(sprintf('%O', 1)).toBe('1')
expect(sprintf('%O', true)).toBe('true')
Expand All @@ -21,12 +45,16 @@ describe('debug/sprintf', () => {
expect(sprintf('%O', [])).toBe('[]')
expect(sprintf('%O', { hello: 'world' })).toBe('{hello:"world"}')
})
test('All together now', () => {
it('formats multiple arguments', () => {
expect(sprintf('%s %O', 'foo', { hello: 'world' })).toBe(
'foo {hello:"world"}'
)
expect(sprintf('%O %s', { hello: 'world' }, 'foo')).toBe(
'{hello:"world"} foo'
)
})
it('supports mismatching numbers of arguments and placeholders', () => {
expect(sprintf('%s %s', 'foo')).toBe('foo undefined')
expect(sprintf('%s %s', 'foo', 'bar', 'baz')).toBe('foo bar')
})
})
7 changes: 6 additions & 1 deletion packages/nuqs/src/debug.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,12 @@ export function debug(message: string, ...args: any[]) {
}
const msg = sprintf(message, ...args)
performance.mark(msg)
console.log(message, ...args)
try {
// Handle React Devtools not being able to console.log('%s', null)
console.log(message, ...args)
} catch (error) {
console.log(msg)
}
}

export function warn(message: string, ...args: any[]) {
Expand Down

0 comments on commit 42a2bee

Please sign in to comment.