diff --git a/errors/NUQS-409.md b/errors/NUQS-409.md new file mode 100644 index 00000000..a44bc5b5 --- /dev/null +++ b/errors/NUQS-409.md @@ -0,0 +1,13 @@ +# Multiple versions of the library are loaded + +This error occurs if two different versions of `next-usequerystate` are +loaded in the same application. + +This may happen if you are using a package that embeds next-usequerystate and +you are also using next-usequerystate directly. + +## Possible Solutions + +Inspect your dependencies for duplicate versions of `next-usequerystate` and +use the `resolutions` field in `package.json` to force all dependencies +to use the same version. diff --git a/errors/NUQS-429.md b/errors/NUQS-429.md new file mode 100644 index 00000000..0c4c23d1 --- /dev/null +++ b/errors/NUQS-429.md @@ -0,0 +1,15 @@ +# URL update rate-limited by the browser + +This error occurs when too many URL updates are attempted in a short period of +time. For example, connecting a query state to a text input that updates on +every keypress, or a slider (``). + +## Possible Solutions + +The library has a built-in throttling mechanism, that can be configured per +instance. See the [throttling](https://github.com/47ng/next-usequerystate#throttling) +docs for more information. + +## Safari + +Safari has a very low rate-limit on URL updates: 100 updates per 30 seconds (or per 10 seconds on Safari 17 and above). diff --git a/packages/next-usequerystate/src/errors.ts b/packages/next-usequerystate/src/errors.ts new file mode 100644 index 00000000..96e9f044 --- /dev/null +++ b/packages/next-usequerystate/src/errors.ts @@ -0,0 +1,10 @@ +export const errors = { + 409: 'Multiple versions of the library are loaded. This may lead to unexpected behavior. Currently using %s, but %s was about to load on top.', + 429: 'URL update rate-limited by the browser. Consider increasing `throttleMs` for keys %s. %O' +} as const + +export function error(code: keyof typeof errors, ...args: any[]) { + const message = `[next-usequerystate] ${errors[code]} + See https://err.sh/47ng/next-usequerystate/NUQS-${code}` + console.error(message, ...args) +} diff --git a/packages/next-usequerystate/src/sync.ts b/packages/next-usequerystate/src/sync.ts index 9568f61b..ae388c18 100644 --- a/packages/next-usequerystate/src/sync.ts +++ b/packages/next-usequerystate/src/sync.ts @@ -1,5 +1,6 @@ import Mitt from 'mitt' import { debug } from './debug' +import { error } from './errors' import { getQueuedValue } from './update-queue' export const SYNC_EVENT_KEY = Symbol('__nextUseQueryState__SYNC__') @@ -44,12 +45,7 @@ function patchHistory() { const patched = history.__nextUseQueryState_patched if (patched) { if (patched !== version) { - // todo: Make this a URL error with more details and resolution instructions - console.warn( - '[next-usequerystate] Multiple versions of the library are loaded. This may lead to unexpected behavior. Currently using %s, but %s was about to load on top.', - patched, - version - ) + error(409, patched, version) } return } diff --git a/packages/next-usequerystate/src/update-queue.ts b/packages/next-usequerystate/src/update-queue.ts index 61c790e3..a2bac014 100644 --- a/packages/next-usequerystate/src/update-queue.ts +++ b/packages/next-usequerystate/src/update-queue.ts @@ -1,5 +1,6 @@ import { debug } from './debug' import type { Options, Router } from './defs' +import { error } from './errors' import { NOSYNC_MARKER } from './sync' import { renderQueryString } from './url-encoding' import { getDefaultThrottle } from './utils' @@ -161,12 +162,10 @@ function flushUpdateQueue(router: Router): [URLSearchParams, null | unknown] { }) } return [search, null] - } catch (error) { - console.error( - // This may fail due to rate-limiting of history methods, - // for example Safari only allows 100 updates in a 30s window. - `useQueryState error updating URL: ${error}` - ) + } catch (err) { + // This may fail due to rate-limiting of history methods, + // for example Safari only allows 100 updates in a 30s window. + error(429, items.map(([key]) => key).join(), err) return [search, error] } }