diff --git a/src/background/proxyService.test.ts b/src/background/proxyService.test.ts index 2c4cd8c922..635ae360c4 100644 --- a/src/background/proxyService.test.ts +++ b/src/background/proxyService.test.ts @@ -176,13 +176,15 @@ describe("proxy service requests", () => { expect(data).toEqual({ foo: 42 }); }); - describe.each([[400], [401], [403], [500]])( + describe.each([[400], [401], [403], [405], [500]])( "remote status: %s", (statusCode) => { it("can proxy remote error", async () => { + const reason = "Bad request"; + axiosMock.onAny().reply(200, { json: {}, - reason: "Bad request", + reason, status_code: statusCode, }); @@ -194,7 +196,7 @@ describe("proxy service requests", () => { const { status, statusText } = ((error as ContextError) .cause as AxiosError).response; expect(status).toEqual(statusCode); - expect(statusText).toEqual("Bad request"); + expect(statusText).toEqual(reason); } }); } diff --git a/src/background/requests.ts b/src/background/requests.ts index 17019fe5fe..ff4f38b8ba 100644 --- a/src/background/requests.ts +++ b/src/background/requests.ts @@ -109,11 +109,14 @@ const backgroundRequest = liftBackground( async (config: AxiosRequestConfig) => { try { return cleanResponse(await axios(config)); - } catch (error) { - // Axios offers its own serialization method, but it doesn't include the response. - // By deleting toJSON, the serialize-error library will use its default serialization + } catch (error: unknown) { + if (isAxiosError(error)) { + // Axios offers its own serialization method, but it doesn't include the response. + // By deleting toJSON, the serialize-error library will use its default serialization + delete error.toJSON; + } + console.trace("Error performing request from background page", { error }); - delete error.toJSON; throw error; } } diff --git a/src/contrib/google/bigquery/handlers.ts b/src/contrib/google/bigquery/handlers.ts index 92a039459e..024f4f3aa9 100644 --- a/src/contrib/google/bigquery/handlers.ts +++ b/src/contrib/google/bigquery/handlers.ts @@ -41,9 +41,9 @@ async function ensureBigQuery(): Promise { // https://github.com/google/google-api-javascript-client/blob/master/docs/reference.md try { await gapi.client.load("bigquery", "v2"); - } catch (error) { + } catch (error: unknown) { console.debug("Error fetching BigQuery API definition", { - error: error.error, + error, }); throw new Error("Error fetching BigQuery API definition"); } diff --git a/src/contrib/google/sheets/append.ts b/src/contrib/google/sheets/append.ts index 336d108fbb..b6bbd6e708 100644 --- a/src/contrib/google/sheets/append.ts +++ b/src/contrib/google/sheets/append.ts @@ -15,14 +15,15 @@ * along with this program. If not, see . */ -import { Effect } from "@/types"; +import { Effect, UnknownObject } from "@/types"; import { BlockArg, BlockOptions, Schema } from "@/core"; import { propertiesToSchema } from "@/validators/generic"; import { isNullOrBlank } from "@/utils"; -import { unary } from "lodash"; +import { isPlainObject, unary } from "lodash"; import { validateRegistryId } from "@/types/helpers"; import { normalizeHeader } from "@/contrib/google/sheets/sheetsHelpers"; import { sheets } from "@/background/messenger/api"; +import { getErrorMessage } from "@/errors"; type CellValue = string | number | null; @@ -103,8 +104,11 @@ export const GOOGLE_SHEETS_APPEND_ID = validateRegistryId( "@pixiebrix/google/sheets-append" ); -function isAuthError(error: { code: number }): boolean { - return [404, 401, 403].includes(error.code); +function isAuthError(error: unknown): boolean { + return ( + isPlainObject(error) && + ([404, 401, 403] as unknown[]).includes((error as UnknownObject).code) + ); } export class GoogleSheetsAppend extends Effect { @@ -120,7 +124,15 @@ export class GoogleSheetsAppend extends Effect { inputSchema: Schema = APPEND_SCHEMA; async effect( - { spreadsheetId, tabName, rowValues: rawValues = {} }: BlockArg, + { + spreadsheetId, + tabName, + rowValues: rawValues = {}, + }: BlockArg<{ + spreadsheetId: string; + tabName: string; + rowValues: Record | RowValue[]; + }>, { logger }: BlockOptions ): Promise { const rowValues = @@ -139,8 +151,10 @@ export class GoogleSheetsAppend extends Effect { console.debug( `Found headers for ${tabName}: ${currentHeaders.join(", ")}` ); - } catch (error) { - logger.warn(`Error retrieving headers: ${error.toString()}`, error); + } catch (error: unknown) { + logger.warn(`Error retrieving headers: ${getErrorMessage(error)}`, { + error, + }); if (isAuthError(error)) { throw error; } diff --git a/src/devTools/Locator.tsx b/src/devTools/Locator.tsx index 42280cfd29..d1a84c5983 100644 --- a/src/devTools/Locator.tsx +++ b/src/devTools/Locator.tsx @@ -25,22 +25,23 @@ import { useAsyncEffect } from "use-async-effect"; import { isEmpty } from "lodash"; import { thisTab } from "@/devTools/utils"; import { detectFrameworks, searchWindow } from "@/contentScript/messenger/api"; +import { getErrorMessage } from "@/errors"; -function useSearchWindow(query: string) { +function useSearchWindow(query: string): [unknown[] | null, unknown | null] { const { tabId } = browser.devtools.inspectedWindow; - const [results, setResults] = useState([]); - const [error, setError] = useState(); + const [results, setResults] = useState([]); + const [error, setError] = useState(); useAsyncEffect( async (isMounted) => { if (!query) return; - setError(undefined); - setResults(undefined); + setError(null); + setResults(null); try { const { results } = await searchWindow(thisTab, query); if (!isMounted()) return; - setResults(results as any); - } catch (error) { + setResults(results); + } catch (error: unknown) { if (!isMounted()) return; setError(error); } @@ -92,7 +93,7 @@ const Locator: React.FunctionComponent = () => { /> - {searchError?.toString()} + {searchError && getErrorMessage(searchError)} {searchResults == null ? ( diff --git a/tsconfig.json b/tsconfig.json index 966e38213d..b5e5725c94 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -10,6 +10,7 @@ "resolveJsonModule": true, "baseUrl": ".", "skipLibCheck": false, + "useUnknownInCatchVariables": true, // TODO: Drop these lines to make TS stricter https://github.com/pixiebrix/pixiebrix-extension/issues/775 "strictNullChecks": false, @@ -19,7 +20,6 @@ "noImplicitReturns": false, "noUnusedParameters": false, "useDefineForClassFields": false, - "useUnknownInCatchVariables": false, // https://github.com/pixiebrix/pixiebrix-extension/issues/779 "paths": { "@/*": ["src/*"], "@img/*": ["img/*"],