fix: a popup reload mid-refresh no longer logs the requests it cancels (closes #218)
check / check (push) Successful in 2m50s
e2e / e2e-chrome (push) Successful in 5m53s
e2e / e2e-firefox (push) Successful in 2m19s

Chrome cancels a closing popup's open requests just after pagehide, and in
the page a cancelled fetch() fails with the same "Failed to fetch" as a
server that cannot be reached. The home screen's transaction list and the
balance refresh logged an error for each, and the e2e suite failed on them.

The popup now aborts an AbortController on pagehide, and those failure
reports check its signal first. End-to-end tests reload the popup with
Blockscout held and require nothing logged, and fail the transaction list
for real and require the failure reported; a unit test covers the balance
refresh. The address and token screens and the new-wallet address scan are
#475.

Model: opus-5-5
This commit was merged in pull request #476.
This commit is contained in:
2026-10-06 09:43:09 +02:00
parent 88c79e7e05
commit 329e64a54d
7 changed files with 195 additions and 21 deletions
+17 -2
View File
@@ -87,7 +87,15 @@ function rawUnits(value) {
// way `holders` already is. Absence is never filled in here: this is the
// upstream of every screen that displays a token amount, so a value invented
// at this point is indistinguishable from a real one everywhere below it.
async function fetchTokenBalances(address, blockscoutUrl, trackedTokens) {
//
// `signal`, passed by the popup, is aborted when the popup closes; a request
// that fails after that was cancelled by the closing and is not logged.
async function fetchTokenBalances(
address,
blockscoutUrl,
trackedTokens,
signal,
) {
try {
const resp = await debugFetch(
blockscoutUrl + "/addresses/" + address + "/token-balances",
@@ -190,18 +198,22 @@ async function fetchTokenBalances(address, blockscoutUrl, trackedTokens) {
}
return balances;
} catch (e) {
log.errorf("fetchTokenBalances failed:", e.message);
if (!signal?.aborted) {
log.errorf("fetchTokenBalances failed:", e.message);
}
return null;
}
}
// Fetch ETH balances, ENS names, and ERC-20 token balances for all addresses.
// `signal` is as for fetchTokenBalances().
async function refreshBalances(
wallets,
rpcUrl,
blockscoutUrl,
trackedTokens,
networkId,
signal,
) {
log.debugf("refreshBalances start, rpc:", urlOrigin(rpcUrl));
const provider = getProvider(rpcUrl, networkId);
@@ -220,6 +232,7 @@ async function refreshBalances(
log.debugf("ETH balance", addr.address, addr.balance);
})
.catch((e) => {
if (signal?.aborted) return;
log.errorf(
"ETH balance failed",
addr.address,
@@ -243,6 +256,7 @@ async function refreshBalances(
);
})
.catch((e) => {
if (signal?.aborted) return;
log.errorf(
"ENS reverse failed",
addr.address,
@@ -258,6 +272,7 @@ async function refreshBalances(
addr.address,
blockscoutUrl,
trackedTokens,
signal,
).then((balances) => {
if (balances !== null) {
addr.tokenBalances = balances;