diff --git a/src/core/client.ts b/src/core/client.ts index 5801dfd3..bc06341c 100644 --- a/src/core/client.ts +++ b/src/core/client.ts @@ -244,6 +244,7 @@ class ApiClient { ) => { const payload = p ?? {}; debug(`Calling ${method}`); + if (signal !== undefined) validateSignal(method, payload, signal); // General config const opts = this.options; const formDataRequired = requiresFormDataUpload(payload); @@ -417,3 +418,34 @@ function createAbortControllerFromSignal(signal?: AbortSignal) { else sig.addEventListener("abort", abort); return { abort, signal: abortController.signal }; } + +function validateSignal( + method: string, + payload: Record, + signal: AbortSignal, +) { + // We use a very simple heuristic to check for AbortSignal instances + // in order to avoid doing a runtime-specific version of `instanceof`. + if (typeof signal?.addEventListener === "function") { + return; + } + + let payload0 = JSON.stringify(payload); + if (payload0.length > 20) { + payload0 = payload0.substring(0, 16) + " ..."; + } + let payload1 = JSON.stringify(signal); + if (payload1.length > 20) { + payload1 = payload1.substring(0, 16) + " ..."; + } + throw new Error( + `Incorrect abort signal instance found! \ +You passed two payloads to '${method}' but you should merge \ +the second one containing '${payload1}' into the first one \ +containing '${payload0}'! If you are using context shortcuts, \ +you may want to use a method on 'ctx.api' instead. + +If you want to prevent such mistakes in the future, \ +consider using TypeScript. https://www.typescriptlang.org/`, + ); +}