Skip to content

Commit

Permalink
unexpected reuseOrCreateTab error should throw
Browse files Browse the repository at this point in the history
  • Loading branch information
darian committed Dec 17, 2024
1 parent ac0ec9f commit c823099
Show file tree
Hide file tree
Showing 3 changed files with 95 additions and 108 deletions.
125 changes: 60 additions & 65 deletions src/background/services/keyAutoAdd.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,76 +92,71 @@ export class KeyAutoAddService {
existingTabId?: TabId,
): Promise<unknown> {
const { resolve, reject, promise } = withResolvers();
try {
const tab = await reuseOrCreateTab(this.browser, url, existingTabId);
this.tab = tab;
const tab = await reuseOrCreateTab(this.browser, url, existingTabId);
this.tab = tab;

const onTabCloseListener: OnTabRemovedCallback = (tabId) => {
if (tabId !== tab.id) return;
this.browser.tabs.onRemoved.removeListener(onTabCloseListener);
reject(new ErrorWithKey('connectWallet_error_tabClosed'));
};
this.browser.tabs.onRemoved.addListener(onTabCloseListener);

const ports = new Set<Runtime.Port>();
const onConnectListener: OnConnectCallback = (port) => {
if (port.name !== CONNECTION_NAME) return;
if (port.error) {
reject(new Error(port.error.message));
return;
}
ports.add(port);

port.postMessage({ action: 'BEGIN', payload });

port.onMessage.addListener(onMessageListener);

port.onDisconnect.addListener(() => {
ports.delete(port);
// wait for connect again so we can send message again if not connected,
// and not errored already (e.g. page refreshed)
});
};

const onTabCloseListener: OnTabRemovedCallback = (tabId) => {
if (tabId !== tab.id) return;
const onMessageListener: OnPortMessageListener = (
message: KeyAutoAddToBackgroundMessage,
port,
) => {
if (message.action === 'SUCCESS') {
this.browser.runtime.onConnect.removeListener(onConnectListener);
this.browser.tabs.onRemoved.removeListener(onTabCloseListener);
reject(new ErrorWithKey('connectWallet_error_tabClosed'));
};
this.browser.tabs.onRemoved.addListener(onTabCloseListener);

const ports = new Set<Runtime.Port>();
const onConnectListener: OnConnectCallback = (port) => {
if (port.name !== CONNECTION_NAME) return;
if (port.error) {
reject(new Error(port.error.message));
return;
}
ports.add(port);

port.postMessage({ action: 'BEGIN', payload });

port.onMessage.addListener(onMessageListener);

port.onDisconnect.addListener(() => {
ports.delete(port);
// wait for connect again so we can send message again if not connected,
// and not errored already (e.g. page refreshed)
});
};

const onMessageListener: OnPortMessageListener = (
message: KeyAutoAddToBackgroundMessage,
port,
) => {
if (message.action === 'SUCCESS') {
this.browser.runtime.onConnect.removeListener(onConnectListener);
this.browser.tabs.onRemoved.removeListener(onTabCloseListener);
resolve(message.payload);
} else if (message.action === 'ERROR') {
this.browser.runtime.onConnect.removeListener(onConnectListener);
this.browser.tabs.onRemoved.removeListener(onTabCloseListener);
const { stepName, details: err } = message.payload;
reject(
new ErrorWithKey(
'connectWalletKeyService_error_failed',
[
stepName,
isErrorWithKey(err.error) ? this.t(err.error) : err.message,
],
isErrorWithKey(err.error) ? err.error : undefined,
),
);
} else if (message.action === 'PROGRESS') {
// can also save progress to show in popup
for (const p of ports) {
if (p !== port) p.postMessage(message);
}
} else {
reject(new Error(`Unexpected message: ${JSON.stringify(message)}`));
resolve(message.payload);
} else if (message.action === 'ERROR') {
this.browser.runtime.onConnect.removeListener(onConnectListener);
this.browser.tabs.onRemoved.removeListener(onTabCloseListener);
const { stepName, details: err } = message.payload;
reject(
new ErrorWithKey(
'connectWalletKeyService_error_failed',
[
stepName,
isErrorWithKey(err.error) ? this.t(err.error) : err.message,
],
isErrorWithKey(err.error) ? err.error : undefined,
),
);
} else if (message.action === 'PROGRESS') {
// can also save progress to show in popup
for (const p of ports) {
if (p !== port) p.postMessage(message);
}
};
} else {
reject(new Error(`Unexpected message: ${JSON.stringify(message)}`));
}
};

this.browser.runtime.onConnect.addListener(onConnectListener);
this.browser.runtime.onConnect.addListener(onConnectListener);

return promise;
} catch (error) {
reject(error);
return promise;
}
return promise;
}

private async validate(walletAddressUrl: string, keyId: string) {
Expand Down
74 changes: 33 additions & 41 deletions src/background/services/openPayments.ts
Original file line number Diff line number Diff line change
Expand Up @@ -780,54 +780,46 @@ export class OpenPaymentsService {
existingTabId?: TabId,
): Promise<InteractionParams> {
const { resolve, reject, promise } = withResolvers<InteractionParams>();
try {
const tab = await reuseOrCreateTab(this.browser, url, existingTabId);
const tab = await reuseOrCreateTab(this.browser, url, existingTabId);

const tabCloseListener: TabRemovedCallback = (tabId) => {
if (tabId !== tab.id) return;
const tabCloseListener: TabRemovedCallback = (tabId) => {
if (tabId !== tab.id) return;

this.browser.tabs.onRemoved.removeListener(tabCloseListener);
reject(new ErrorWithKey('connectWallet_error_tabClosed'));
};
this.browser.tabs.onRemoved.removeListener(tabCloseListener);
reject(new ErrorWithKey('connectWallet_error_tabClosed'));
};

const getInteractionInfo: TabUpdateCallback = async (
tabId,
changeInfo,
) => {
if (tabId !== tab.id) return;
try {
const tabUrl = new URL(changeInfo.url || '');
const interactRef = tabUrl.searchParams.get('interact_ref');
const hash = tabUrl.searchParams.get('hash');
const result = tabUrl.searchParams.get('result');

if (
(interactRef && hash) ||
result === 'grant_rejected' ||
result === 'grant_invalid'
) {
this.browser.tabs.onUpdated.removeListener(getInteractionInfo);
this.browser.tabs.onRemoved.removeListener(tabCloseListener);
}
const getInteractionInfo: TabUpdateCallback = async (tabId, changeInfo) => {
if (tabId !== tab.id) return;
try {
const tabUrl = new URL(changeInfo.url || '');
const interactRef = tabUrl.searchParams.get('interact_ref');
const hash = tabUrl.searchParams.get('hash');
const result = tabUrl.searchParams.get('result');

if (interactRef && hash) {
resolve({ interactRef, hash, tabId });
} else if (result === 'grant_rejected') {
reject(new ErrorWithKey('connectWallet_error_grantRejected'));
}
} catch {
/* do nothing */
if (
(interactRef && hash) ||
result === 'grant_rejected' ||
result === 'grant_invalid'
) {
this.browser.tabs.onUpdated.removeListener(getInteractionInfo);
this.browser.tabs.onRemoved.removeListener(tabCloseListener);
}
};

this.browser.tabs.onRemoved.addListener(tabCloseListener);
this.browser.tabs.onUpdated.addListener(getInteractionInfo);
if (interactRef && hash) {
resolve({ interactRef, hash, tabId });
} else if (result === 'grant_rejected') {
reject(new ErrorWithKey('connectWallet_error_grantRejected'));
}
} catch {
/* do nothing */
}
};

this.browser.tabs.onRemoved.addListener(tabCloseListener);
this.browser.tabs.onUpdated.addListener(getInteractionInfo);

return promise;
} catch (error) {
reject(error);
return promise;
}
return promise;
}

async disconnectWallet() {
Expand Down
4 changes: 2 additions & 2 deletions src/background/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,13 +99,13 @@ export const reuseOrCreateTab = async (
try {
const tab = await browser.tabs.get(tabId ?? -1);
if (!tab.id) {
throw new Error('Unexpected: tab does not have id');
throw new Error('Could not retrieve tab.');
}
return (await browser.tabs.update(tab.id, { url })) as Tab;
} catch {
const tab = await browser.tabs.create({ url });
if (!tab.id) {
throw new Error('Unexpected: tab does not have id');
throw new Error('Newly created tab does not have the id property set.');
}
return tab as Tab;
}
Expand Down

0 comments on commit c823099

Please sign in to comment.