diff --git a/src/api.ts b/src/api.ts index 3d634a7d..00e4a944 100644 --- a/src/api.ts +++ b/src/api.ts @@ -42,10 +42,10 @@ router.get('/scores/:proposalId', async (req, res) => { try { const result = await serve(proposalId, updateProposalAndVotes, [proposalId]); return res.json({ result }); - } catch (e) { + } catch (e: any) { capture(e); log.warn(`[api] updateProposalAndVotes() failed ${proposalId}, ${JSON.stringify(e)}`); - return res.json({ error: 'failed', message: e }); + return res.json({ error: 'failed', message: e.message || e }); } }); diff --git a/src/scores.ts b/src/scores.ts index d2780bbf..4ce5ef06 100644 --- a/src/scores.ts +++ b/src/scores.ts @@ -96,6 +96,11 @@ async function updateProposalScores(proposalId: string, scores: any, votes: numb ]); } +async function invalidateProposalScore(proposalId: string) { + const query = `UPDATE proposals SET scores_state = ? WHERE id = ? LIMIT 1;`; + await db.queryAsync(query, ['invalid', proposalId]); +} + const pendingRequests = {}; export async function updateProposalAndVotes(proposalId: string, force = false) { @@ -114,7 +119,7 @@ export async function updateProposalAndVotes(proposalId: string, force = false) (proposal.votes > 30000 && proposal.scores_updated > ts - 300) || pendingRequests[proposalId] ) { - console.log( + log.info( 'ignore score calculation', proposal.space, proposalId, @@ -171,10 +176,22 @@ export async function updateProposalAndVotes(proposalId: string, force = false) if (!isFinal) await updateVotesVp(votes, vpState, proposalId); // Store scores - await updateProposalScores(proposalId, results, votes.length); - log.info( - `[scores] Proposal updated ${proposal.id}, ${proposal.space}, ${results.scores_state}, ${votes.length}` - ); + try { + await updateProposalScores(proposalId, results, votes.length); + log.info( + `[scores] Proposal updated ${proposal.id}, ${proposal.space}, ${results.scores_state}, ${votes.length}` + ); + } catch (e: any) { + if (e.code === 'ER_WARN_DATA_OUT_OF_RANGE') { + log.info(`[scores] Invalid final scores_total: ${results.scores_total}`, e); + if (proposal.state === 'closed') { + await invalidateProposalScore(proposalId); + } + throw new Error('Invalid out of range score'); + } else { + throw e; + } + } delete pendingRequests[proposalId]; return true;