Skip to content

Revert "fix: manually surface LIP-118 poll while subgraph indexing is behind"#753

Merged
rickstaa merged 1 commit into
mainfrom
revert-734-fix/manually-list-lip118-poll
Jul 22, 2026
Merged

Revert "fix: manually surface LIP-118 poll while subgraph indexing is behind"#753
rickstaa merged 1 commit into
mainfrom
revert-734-fix/manually-list-lip118-poll

Conversation

@rickstaa

@rickstaa rickstaa commented Jul 22, 2026

Copy link
Copy Markdown
Member

Reverts #734 now the new subgraph is indexed again.

Summary by CodeRabbit

  • Bug Fixes
    • Removed outdated fallback governance polls previously shown during indexing outages.
    • Voting pages now display only polls available from the live governance data source.
    • Poll details show an error when live data cannot be loaded.
    • Improved error propagation when retrieving total voting stake.

Copilot AI review requested due to automatic review settings July 22, 2026 19:47
@rickstaa
rickstaa requested a review from ECWireless as a code owner July 22, 2026 19:47
@vercel

vercel Bot commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
explorer-arbitrum-one Ready Ready Preview, Comment Jul 22, 2026 7:51pm

Request Review

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Reverts the prior stopgap that manually surfaced governance polls and tolerated subgraph outages, returning the voting UI/data flow to relying solely on the subgraph now that indexing has recovered.

Changes:

  • Remove manual poll merging/fallback logic from voting list/detail pages and layout poll counts.
  • Delete the constants/manualPolls.ts stopgap and related UI messaging.
  • Restore original getTotalStake behavior by removing the try/catch degradation path.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
pages/voting/index.tsx Removes manual poll merging and re-gates poll list hydration on subgraph data presence.
pages/voting/[poll].tsx Removes manual poll fallback for detail view and associated “indexing behind” messaging.
lib/api/polls.ts Removes graceful fallback when ProtocolByBlock query fails (reverting to throw-on-error behavior).
layouts/main.tsx Removes manual poll merging from active poll count computation.
constants/manualPolls.ts Deletes the temporary manual poll definitions and merge helpers.
Comments suppressed due to low confidence (1)

layouts/main.tsx:186

  • pollData?.polls.filter(...) can throw when pollData is undefined, because optional chaining only applies to pollData and not to polls. This will break the layout before the polls query resolves.
  const totalActivePolls = useMemo(
    () =>
      pollData?.polls.filter(
        (p) =>
          (currentRound?.currentL1Block ?? Number.MAX_VALUE) <=
          parseInt(p.endBlock)
      ).length,
    [currentRound?.currentL1Block, pollData]

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread pages/voting/[poll].tsx
Comment on lines 91 to 99
useEffect(() => {
const init = async () => {
// Fall back to a manually-listed poll when the subgraph doesn't have it
// (e.g. created while indexing was down), so it stays viewable/votable.
const source = data?.poll ?? getManualPoll(pollId);
if (source && currentRound?.currentL1Block) {
if (data && currentRound?.currentL1Block) {
const response = await getPollExtended(
source,
data.poll,
currentRound.currentL1Block
);
setPollData(response);
}
Comment thread pages/voting/[poll].tsx
Comment on lines +104 to 106
if (pollError) {
return <FourZeroFour />;
}
Comment thread pages/voting/index.tsx
Comment on lines 52 to 60
useEffect(() => {
// Render as soon as the (on-chain) current round is available, even if the
// subgraph query returned nothing, so manually-listed polls still show while
// indexing is down. mergeManualPolls tolerates `data` being undefined.
if (currentRound?.currentL1Block) {
if (data && currentRound?.currentL1Block) {
const init = async () => {
setPolls(
await Promise.all(
mergeManualPolls(data?.polls).map((p) =>
(data?.polls ?? []).map((p) =>
getPollExtended(p, currentRound.currentL1Block)
)
)
@coderabbitai

coderabbitai Bot commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

The manual poll stopgap and its consumers were removed. Voting pages and active poll counts now use subgraph results directly, while getTotalStake no longer catches Apollo query failures.

Changes

Poll data flow

Layer / File(s) Summary
Voting poll source and detail handling
pages/voting/index.tsx, pages/voting/[poll].tsx
Voting pages no longer merge or retrieve manual polls, require subgraph data before initialization, and treat poll errors as blocking errors.
Active poll count integration
layouts/main.tsx
Active poll totals are filtered directly from subgraph-provided polls.
Total stake query behavior
lib/api/polls.ts
getTotalStake directly returns the Apollo query result without local error handling or warning logging.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Possibly related PRs

Suggested reviewers: ecwireless, copilot

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Description check ⚠️ Warning The description is far too sparse and omits required template sections like changes, testing, impact, and risk. Fill in the template sections: description, type of change, related issues, changes made, testing, impact/risk, and rollback plan.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately states that this PR reverts the manual LIP-118 poll workaround.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch revert-734-fix/manually-list-lip118-poll

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

ESLint install timed out. The project may have too many dependencies for the sandbox.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
pages/voting/index.tsx (1)

53-67: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Add a shared failure path for asynchronous poll initialization. Poll enrichment can throw during IPfs fetch, GraphQL stake lookup, L2 range lookup, or estimated end time calculation, but pages/voting/index.tsx leaves the spinner rendering and pages/voting/[poll].tsx falls back to the null-Poll spinner state. Handle rejected initialization with try/catch/finally and render an explicit, recoverable error state.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@pages/voting/index.tsx` around lines 53 - 67, Add a shared recoverable error
state for asynchronous poll initialization in pages/voting/index.tsx and
pages/voting/[poll].tsx: wrap getPollExtended initialization in
try/catch/finally, record the failure, and always clear loading in finally so
rejected enrichment cannot leave the spinner indefinitely. Update the
corresponding rendering paths to show an explicit error state with a recovery
action instead of the null-Poll spinner fallback; apply these changes at
pages/voting/index.tsx lines 53-67 and pages/voting/[poll].tsx lines 91-102.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@lib/api/polls.ts`:
- Around line 172-190: Restore error handling in getTotalStake around the Apollo
client.query call so network or GraphQL failures are caught, logged using the
existing logging mechanism, and result in undefined rather than rejecting.
Preserve the current successful response behavior and ensure getPollExtended
continues to degrade gracefully when the subgraph is unavailable.

In `@pages/voting/`[poll].tsx:
- Around line 104-105: Update the error handling in the poll page around
pollError so only a confirmed missing poll—poll === null after a successful
fetch or an explicitly missing-poll GraphQL error—renders FourZeroFour. Route
network, server, gateway, and other execution failures to the existing
error/retry state, preserving normal rendering for successful polls.
- Around line 93-98: Guard the getPollExtended call so it runs only when
data?.poll is non-null and currentRound.currentL1Block is available. In the
successful-query branch where data.poll is missing, follow the existing 404
response path instead of constructing poll data from null.

---

Outside diff comments:
In `@pages/voting/index.tsx`:
- Around line 53-67: Add a shared recoverable error state for asynchronous poll
initialization in pages/voting/index.tsx and pages/voting/[poll].tsx: wrap
getPollExtended initialization in try/catch/finally, record the failure, and
always clear loading in finally so rejected enrichment cannot leave the spinner
indefinitely. Update the corresponding rendering paths to show an explicit error
state with a recovery action instead of the null-Poll spinner fallback; apply
these changes at pages/voting/index.tsx lines 53-67 and pages/voting/[poll].tsx
lines 91-102.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 44f59002-d2f9-48a1-9751-01f960a24544

📥 Commits

Reviewing files that changed from the base of the PR and between 6a167af and 9e26cb3.

📒 Files selected for processing (5)
  • constants/manualPolls.ts
  • layouts/main.tsx
  • lib/api/polls.ts
  • pages/voting/[poll].tsx
  • pages/voting/index.tsx
💤 Files with no reviewable changes (1)
  • constants/manualPolls.ts

Comment thread lib/api/polls.ts
Comment on lines 172 to +190
const getTotalStake = async (l2BlockNumber?: number | undefined) => {
try {
const client = getApollo();

const protocolResponse = await client.query<
ProtocolByBlockQuery,
ProtocolByBlockQueryVariables
>({
query: ProtocolByBlockDocument,
variables: l2BlockNumber
? {
block: {
number: l2BlockNumber,
},
}
: undefined,
fetchPolicy: "network-only",
});

return protocolResponse?.data?.protocol?.totalActiveStake;
} catch (err) {
// The subgraph can be unavailable (e.g. an indexing halt). Total stake only
// feeds participation percentages, so degrade gracefully instead of failing
// the whole poll render — this keeps manually-listed polls viewable/votable.
const detail = err instanceof Error ? err.message : String(err);
console.warn(`Could not fetch total stake from subgraph (${detail})`);
return undefined;
}
const client = getApollo();

const protocolResponse = await client.query<
ProtocolByBlockQuery,
ProtocolByBlockQueryVariables
>({
query: ProtocolByBlockDocument,
variables: l2BlockNumber
? {
block: {
number: l2BlockNumber,
},
}
: undefined,
fetchPolicy: "network-only",
});

return protocolResponse?.data?.protocol?.totalActiveStake;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Unguarded Apollo query — subgraph failures now propagate unhandled.

getTotalStake no longer catches failures from client.query. With Apollo's default errorPolicy: "none", a network/GraphQL error rejects the promise, and since getPollExtended awaits this with no try/catch either, any subgraph hiccup will now throw through the poll rendering path instead of degrading gracefully (previously logged + returned undefined). Given that subgraph instability is exactly what motivated the original manual-poll workaround this PR reverts, losing this safety net reintroduces the failure mode it was built to avoid.

If reverting to pre-#734 behavior is intentional, worth confirming the team is fine with poll pages failing outright on subgraph errors rather than degrading.

🛡️ Optional fix to restore graceful degradation
 const getTotalStake = async (l2BlockNumber?: number | undefined) => {
   const client = getApollo();
 
-  const protocolResponse = await client.query<
-    ProtocolByBlockQuery,
-    ProtocolByBlockQueryVariables
-  >({
-    query: ProtocolByBlockDocument,
-    variables: l2BlockNumber
-      ? {
-          block: {
-            number: l2BlockNumber,
-          },
-        }
-      : undefined,
-    fetchPolicy: "network-only",
-  });
-
-  return protocolResponse?.data?.protocol?.totalActiveStake;
+  try {
+    const protocolResponse = await client.query<
+      ProtocolByBlockQuery,
+      ProtocolByBlockQueryVariables
+    >({
+      query: ProtocolByBlockDocument,
+      variables: l2BlockNumber
+        ? {
+            block: {
+              number: l2BlockNumber,
+            },
+          }
+        : undefined,
+      fetchPolicy: "network-only",
+    });
+
+    return protocolResponse?.data?.protocol?.totalActiveStake;
+  } catch (err) {
+    console.warn(`Could not fetch total stake: ${err}`);
+    return undefined;
+  }
 };
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const getTotalStake = async (l2BlockNumber?: number | undefined) => {
try {
const client = getApollo();
const protocolResponse = await client.query<
ProtocolByBlockQuery,
ProtocolByBlockQueryVariables
>({
query: ProtocolByBlockDocument,
variables: l2BlockNumber
? {
block: {
number: l2BlockNumber,
},
}
: undefined,
fetchPolicy: "network-only",
});
return protocolResponse?.data?.protocol?.totalActiveStake;
} catch (err) {
// The subgraph can be unavailable (e.g. an indexing halt). Total stake only
// feeds participation percentages, so degrade gracefully instead of failing
// the whole poll render — this keeps manually-listed polls viewable/votable.
const detail = err instanceof Error ? err.message : String(err);
console.warn(`Could not fetch total stake from subgraph (${detail})`);
return undefined;
}
const client = getApollo();
const protocolResponse = await client.query<
ProtocolByBlockQuery,
ProtocolByBlockQueryVariables
>({
query: ProtocolByBlockDocument,
variables: l2BlockNumber
? {
block: {
number: l2BlockNumber,
},
}
: undefined,
fetchPolicy: "network-only",
});
return protocolResponse?.data?.protocol?.totalActiveStake;
const getTotalStake = async (l2BlockNumber?: number | undefined) => {
const client = getApollo();
try {
const protocolResponse = await client.query<
ProtocolByBlockQuery,
ProtocolByBlockQueryVariables
>({
query: ProtocolByBlockDocument,
variables: l2BlockNumber
? {
block: {
number: l2BlockNumber,
},
}
: undefined,
fetchPolicy: "network-only",
});
return protocolResponse?.data?.protocol?.totalActiveStake;
} catch (err) {
console.warn(`Could not fetch total stake: ${err}`);
return undefined;
}
};
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@lib/api/polls.ts` around lines 172 - 190, Restore error handling in
getTotalStake around the Apollo client.query call so network or GraphQL failures
are caught, logged using the existing logging mechanism, and result in undefined
rather than rejecting. Preserve the current successful response behavior and
ensure getPollExtended continues to degrade gracefully when the subgraph is
unavailable.

Comment thread pages/voting/[poll].tsx
Comment on lines +93 to 98
if (data && currentRound?.currentL1Block) {
const response = await getPollExtended(
source,
data.poll,
currentRound.currentL1Block
);
setPollData(response);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== candidate files =="
fd -a 'poll.*\.(ts|tsx)$|voting.*\.(ts|tsx)$' . | sed 's#^\./##' | head -100

echo "== target file outline/size =="
wc -l pages/voting/[poll].tsx 2>/dev/null || true
ast-grep outline "pages/voting/[poll].tsx" 2>/dev/null || true

echo "== relevant lines =="
cat -n "pages/voting/[poll].tsx" | sed -n '1,180p'

echo "== getPollExtended usages/definition =="
rg -n "function getPollExtended|const getPollExtended|getPollExtended\(" . -S

Repository: livepeer/explorer

Length of output: 7063


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Locate source without relying on exact path
echo "== git ls files matching poll_extended or polling =="
git ls-files | rg -i 'poll|extended' | head -120

echo "== search api call helpers =="
rg -n "getPollExtended|poll_extended|extended" . -S | head -200

Repository: livepeer/explorer

Length of output: 1755


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== lib/api/polls.ts =="
cat -n lib/api/polls.ts | sed -n '1,180p'

echo "== apollo schema/types around poll =="
cat -n apollo/createSchema.ts | sed -n '1,180p'
rg -n -C 4 "poll|Poll|id: ID|status: PollStatus|currentL1Block" apollo queries lib/api pages/voting -S | head -260

echo "== all uses of pollData attributes/status =="
cat -n pages/voting/[poll].tsx | sed -n '180,430p'

Repository: livepeer/explorer

Length of output: 32155


🌐 Web query:

GraphQL Livepeer subgraph Poll id query poll(id: $id): Poll generated schema optional id argument

💡 Result:

In the Livepeer subgraph schema, the Poll entity is defined with an ID field of type ID! [1]. When querying individual entities in a GraphQL subgraph, you can typically retrieve a specific entity by its ID using the singular form of the entity name as a query field (e.g., poll(id: $id): Poll) [2][3]. Since the Poll entity's id field is marked as non-nullable (ID!) [1], the query input for retrieving a single poll by its ID requires an ID argument. While the schema definition itself specifies the ID field's requirements, the generated GraphQL schema for The Graph subgraphs includes top-level query fields for each entity, which natively support fetching by the entity's ID [1][2]. If you are writing a query to fetch a specific poll, you would structure it as follows: query GetPoll($id: String!) { poll(id: $id) { id proposal endBlock quorum quota tally { id } } } In this structure, the id argument is required to identify the specific Poll entity [1][2]. If you are encountering issues where the id argument appears to be optional or missing in certain documentation or generated types, ensure that your client-side GraphQL generator (e.g., Apollo Client) is correctly pointing to the latest subgraph schema, as entity-specific query fields for objects with ID types are standard for subgraphs [2][3].

Citations:


🌐 Web query:

The Graph generated singular entity query poll(id) null response when id not found

💡 Result:

In The Graph, a singular entity query (e.g., entity(id: "123")) returns a standard GraphQL response where the data field for that entity is null if the requested ID is not found [1][2]. When this occurs, the response typically follows this structure: { "data": { "entityName": null }, "errors": [ { "message": "Entity not found", "locations": [{"line": 2, "column": 3}], "path": ["entityName"] } ] } Key technical points: 1. Expected Behavior: Returning null for a missing entity is the standard GraphQL behavior for nullable singular query fields [1][2][3]. 2. Error Response: While the data value is null, The Graph often includes an entry in the errors array explicitly stating "Entity not found" [1][2]. 3. Troubleshooting: If you are encountering unexpected null results when you believe an entity should exist, verify that the id string passed in the query exactly matches the ID stored in the subgraph database [4]. Common issues include: - Case sensitivity (e.g., "0x0b" vs "0xb"). - Incorrect padding or formatting of Hex/Bytes IDs [4]. - Synchronization delays where the entity has not yet been indexed [4]. If you are seeing a null response without an error, or if you suspect it should be returning an object, double-check your ID generation logic in your subgraph's mapping code to ensure it aligns perfectly with the queries you are performing [4].

Citations:


🌐 Web query:

site:github.com/livepeer/explorer apollo/subgraph.ts generated types usePollQuery poll data

💡 Result:

The file apollo/subgraph.ts in the livepeer/explorer repository is an auto-generated file containing Apollo Client types and hooks derived from GraphQL operations [1][2]. It is not a library-provided file but rather a product of code generation, typically using a tool like GraphQL Code Generator [1]. In this context, usePollQuery is a generated React hook that corresponds to a GraphQL query defined (usually in a.graphql file) within the project [2]. When you define a query named Poll (e.g., in a file like queries/poll.graphql), the code generation process automatically creates a corresponding React hook named usePollQuery [2]. To work with poll data via this hook: 1. Identification: The hook is generated based on the name of the operation in your.graphql files. If your operation is named query Poll, the generated hook will be usePollQuery [2]. 2. Usage: You can use this hook in your React components to fetch poll data from the subgraph [2]. It returns an object containing the data, loading state, error state, and other standard Apollo Client hook properties [2]. 3. Generation: Because apollo/subgraph.ts is auto-generated, you should not edit it directly [1]. Instead, update the underlying GraphQL query files (e.g., in the queries/ directory) and re-run your generation command (often configured in codegen.yml) to update the types and hooks [1][2]. If you are trying to access specific poll data, ensure that your GraphQL query explicitly requests the necessary fields (such as poll ID, choiceID, or voter details) and that your codegen configuration is set to output React hooks [2].

Citations:


Guard data.poll before calling getPollExtended.

  • Problem: data can be successfully populated with data.poll === null, but this still calls getPollExtended(null, ...), which builds a PollExtended from null and can render a poll page with status === "active" and endBlock === 0.
  • Why it matters: Unknown/missing poll IDs bypass the existing 404 path and show malformed poll data instead.
  • Suggested fix: Only call getPollExtended when data?.poll is non-null; otherwise return 404 for a successful query with no matching poll.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@pages/voting/`[poll].tsx around lines 93 - 98, Guard the getPollExtended call
so it runs only when data?.poll is non-null and currentRound.currentL1Block is
available. In the successful-query branch where data.poll is missing, follow the
existing 404 response path instead of constructing poll data from null.

Comment thread pages/voting/[poll].tsx
Comment on lines +104 to 105
if (pollError) {
return <FourZeroFour />;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "## files"
git ls-files | sed -n '1,120p'
echo

echo "## target outline/size"
wc -l pages/voting/\[poll\].tsx 2>/dev/null || true
ast-grep outline 'pages/voting/[poll].tsx' 2>/dev/null || true
echo

echo "## target lines 1-180"
cat -n 'pages/voting/[poll].tsx' | sed -n '1,180p'
echo

echo "## hunt for FourZeroFour and pollError usages"
rg -n "FourZeroFour|pollError|apolloError|networkError|graphQLErrors|NotFoundError|Poll" . --glob '!node_modules' --glob '!dist' --glob '!build' | sed -n '1,200p'

Repository: livepeer/explorer

Length of output: 39702


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "## files"
git ls-files | sed -n '1,120p'
echo

echo "## target outline/size"
wc -l 'pages/voting/[poll].tsx' 2>/dev/null || true
ast-grep outline 'pages/voting/[poll].tsx' 2>/dev/null || true
echo

echo "## target lines 1-180"
cat -n 'pages/voting/[poll].tsx' | sed -n '1,180p'
echo

echo "## hunt for FourZeroFour and pollError usages"
rg -n "FourZeroFour|pollError|apolloError|networkError|graphQLErrors|NotFoundError|Poll" . --glob '!node_modules' --glob '!dist' --glob '!build' | sed -n '1,200p'

Repository: livepeer/explorer

Length of output: 39584


Do not map every Apollo error to 404.

  • Problem: pollError can be a network failure, server/gateway error, or execution error, but this branch returns <FourZeroFour /> for all of them.
  • Why it matters: Subgraph or network outages make a valid poll URL look like “not found,” hiding recoverable failures from the user.
  • Suggested fix: Only show 404 for poll === null after a successful fetch, or for GraphQL errors that explicitly represent a missing poll. Render an error/retry state for network and other non-missing-entity failures.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@pages/voting/`[poll].tsx around lines 104 - 105, Update the error handling in
the poll page around pollError so only a confirmed missing poll—poll === null
after a successful fetch or an explicitly missing-poll GraphQL error—renders
FourZeroFour. Route network, server, gateway, and other execution failures to
the existing error/retry state, preserving normal rendering for successful
polls.

@rickstaa
rickstaa merged commit 72a24a1 into main Jul 22, 2026
10 checks passed
@rickstaa
rickstaa deleted the revert-734-fix/manually-list-lip118-poll branch July 22, 2026 19:59
moudi-network pushed a commit to moudi-network/explorer that referenced this pull request Jul 24, 2026
… behind …" (livepeer#753)

This reverts commit 29fd3cc now the new subgraph is fully indexed.
moudi-network pushed a commit to moudi-network/explorer that referenced this pull request Jul 24, 2026
… behind …" (livepeer#753)

This reverts commit 29fd3cc now the new subgraph is fully indexed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants