Skip to content

Commit 99de368

Browse files
committed
fix(settings): Handle null Apollo cache reads safely
Because: * Sentry reports type errors when GQL cache reads return null This commit: * Updates Apollo readQuery usage to handle null results safely * Tightens Typescript typing for cache reads to avoid destructuring null * Switches from `cache.readQuery` to `client.readQuery` for safer, supported cache access * Removes unused getProfileInfo getter Closes #FXA-12756
1 parent 1d727ad commit 99de368

2 files changed

Lines changed: 31 additions & 39 deletions

File tree

packages/fxa-settings/src/models/Account.ts

Lines changed: 12 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -388,13 +388,17 @@ export class Account implements AccountData {
388388
}
389389
}
390390

391-
private get data() {
392-
const { account } = this.apolloClient.cache.readQuery<{
393-
account: AccountData;
394-
}>({
391+
private get data(): AccountData {
392+
// readQuery is cache-only by default
393+
const result = this.apolloClient.readQuery<{ account: AccountData }>({
395394
query: GET_ACCOUNT,
396-
})!;
397-
return account;
395+
});
396+
397+
if (!result?.account) {
398+
throw new Error('Account data not loaded from Apollo cache');
399+
}
400+
401+
return result.account;
398402
}
399403

400404
get loading() {
@@ -541,32 +545,12 @@ export class Account implements AccountData {
541545
);
542546
}
543547

544-
async getSecurityEvents() {
548+
async getSecurityEvents(): Promise<SecurityEvent[]> {
545549
const { data } = await this.apolloClient.query({
546550
fetchPolicy: 'network-only',
547551
query: GET_SECURITY_EVENTS,
548552
});
549-
const { account } = data;
550-
return account.securityEvents;
551-
}
552-
553-
async getProfileInfo() {
554-
try {
555-
const { data } = await this.apolloClient.query({
556-
fetchPolicy: 'network-only',
557-
query: GET_PROFILE_INFO,
558-
});
559-
const { account } = data;
560-
return account as ProfileInfo;
561-
} catch (err) {
562-
const errno = (err as ApolloError).graphQLErrors[0].extensions?.errno as
563-
| number
564-
| undefined;
565-
if (errno && AuthUiErrorNos[errno]) {
566-
throw AuthUiErrorNos[errno];
567-
}
568-
throw AuthUiErrors.UNEXPECTED_ERROR;
569-
}
553+
return data?.account?.securityEvents ?? [];
570554
}
571555

572556
async getRecoveryKeyBundle(

packages/fxa-settings/src/models/contexts/SettingsContext.ts

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import React from 'react';
77
import config from '../../lib/config';
88
import firefox, { FirefoxCommand } from '../../lib/channels/firefox';
99
import { createApolloClient } from '../../lib/gql';
10-
import { Account, GET_PROFILE_INFO } from '../Account';
10+
import { GET_PROFILE_INFO } from '../Account';
1111
import { AlertBarInfo } from '../AlertBarInfo';
1212

1313
export const INITIAL_SETTINGS_QUERY = gql`
@@ -95,17 +95,25 @@ export function initializeSettingsContext() {
9595
const alertBarInfo = new AlertBarInfo();
9696
const apolloClient = createApolloClient(config.servers.gql.url);
9797

98+
const GET_UID_QUERY = gql`
99+
query GetUid {
100+
account {
101+
uid
102+
}
103+
}
104+
`;
105+
98106
const isForCurrentUser = (event: Event) => {
99-
const { account } = apolloClient.cache.readQuery<{ account: Account }>({
100-
query: gql`
101-
query GetUid {
102-
account {
103-
uid
104-
}
105-
}
106-
`,
107-
})!;
108-
return account.uid === (event as CustomEvent).detail.uid;
107+
const data = apolloClient.readQuery<{ account: { uid: string } }>({
108+
query: GET_UID_QUERY,
109+
});
110+
111+
if (!data?.account?.uid) {
112+
return false;
113+
}
114+
const currentUid = data.account.uid;
115+
const eventUid = (event as CustomEvent).detail?.uid;
116+
return currentUid != null && currentUid === eventUid;
109117
};
110118

111119
firefox.addEventListener(FirefoxCommand.ProfileChanged, (event) => {

0 commit comments

Comments
 (0)