{"record":{"id":"f3c2ae30d8a0983b","repo":"Molunerfinn/PicGo","slug":"result-error-dynamic-message-propagated-from-rpc-f3c2ae","errorCode":null,"errorMessage":"result.error (dynamic message propagated from RPC failure)","messagePattern":"result\\.error \\(dynamic message propagated from RPC failure\\)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/renderer/queries/picgo-cloud-billing.ts","lineNumber":13,"sourceCode":"import { useQuery } from '@tanstack/react-query'\nimport type { IPicGoCloudBillingOverview } from '#/types/cloud'\nimport { cloudAdapter } from '@/adapters/cloud'\nimport { rendererQueryClient } from './query-client'\n\nexport const PicGoCloudBillingQueryKeys = {\n  overview: ['picgo-cloud', 'billing'] as const\n}\n\nasync function fetchPicGoCloudBillingOverview (): Promise<IPicGoCloudBillingOverview | null> {\n  const result = await cloudAdapter.getBillingOverview()\n  if (!result.success) {\n    throw new Error(result.error)\n  }\n  return result.data\n}\n\nexport function usePicGoCloudBillingQuery () {\n  return useQuery({\n    queryKey: PicGoCloudBillingQueryKeys.overview,\n    queryFn: fetchPicGoCloudBillingOverview,\n    refetchOnWindowFocus: true\n  })\n}\n\nexport async function invalidatePicGoCloudBillingQuery () {\n  await rendererQueryClient.invalidateQueries({\n    queryKey: PicGoCloudBillingQueryKeys.overview\n  })\n}\n","sourceCodeStart":1,"sourceCodeEnd":31,"githubUrl":"https://github.com/Molunerfinn/PicGo/blob/07ec7068a5512344da093d49a8408fa63ba3421e/src/renderer/queries/picgo-cloud-billing.ts#L1-L31","documentation":"fetchPicGoCloudBillingOverview throws Error(result.error) when the PICGO_CLOUD_GET_BILLING_OVERVIEW RPC via cloudAdapter.getBillingOverview() reports success:false, surfacing the main-process failure text to TanStack Query. This turns a structured RPC failure envelope into a thrown error so the billing query transitions to error state.","triggerScenarios":"Billing overview RPC fails: no PicGo Cloud session, token expired, billing service unreachable, server-side error for the account, or the main handler returns success:false with a message.","commonSituations":"Visiting the billing page while offline; session invalidated server-side; billing endpoint temporarily down; account in grace/frozen state that blocks billing data.","solutions":["Read query.error.message to identify the underlying failure (auth vs network vs server).","Re-authenticate via cloudAdapter.login() then invalidate ['picgo-cloud','billing'].","Retry after connectivity is restored; enable TanStack Query retry for transient errors.","Handle null data gracefully — the fetcher returns IPicGoCloudBillingOverview | null on success, so only genuine failures throw."],"exampleFix":"null","handlingStrategy":"try-catch","validationCode":"const userInfo = rendererQueryClient.getQueryData<IPicGoCloudUserInfo | null>(['picgo-cloud', 'user-info'])\nif (!userInfo) throw new Error('PicGo Cloud login required before fetching billing overview')","typeGuard":"function hasBillingData(r: unknown): r is { success: true, data: IPicGoCloudBillingOverview | null } {\n  return typeof r === 'object' && r !== null && (r as { success?: boolean }).success === true\n}","tryCatchPattern":"try {\n  const overview = await rendererQueryClient.fetchQuery({ queryKey: ['picgo-cloud', 'billing'], queryFn: fetchPicGoCloudBillingOverview })\n} catch (e) {\n  toast.error(e instanceof Error ? e.message : i18n.t('OPERATION_FAILED'))\n  // render an empty billing state instead of crashing the page\n}","preventionTips":["Require an active PicGo Cloud session before mounting billing UI.","Enable query retry with backoff for transient network errors.","Render a distinct error/empty state for the billing panel using query.isError.","Invalidate the billing query after login/logout rather than letting stale fetches fail."],"tags":["rpc","react-query","network","billing"],"backgroundTag":"rpc-error-propagation","analyzedSha":"07ec7068a5512344da093d49a8408fa63ba3421e","analyzedAt":"2026-08-30T01:45:22.289Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}