Fix duplicate answer bug - update timestamp before processing

Root cause: When setRemoteDescription failed, lastPollTimestamp was
never updated, causing the server to return the same answer repeatedly.

Solution:
1. Update lastPollTimestamp BEFORE processing answers
2. Calculate max timestamp from all received answers upfront
3. Don't throw on setRemoteDescription errors - just log and continue
4. This ensures we advance the timestamp even if processing fails

This prevents the infinite loop of:
- Poll returns answer
- Processing fails
- Timestamp not updated
- Next poll returns same answer
- Repeat

Now the timestamp advances regardless of processing success,
preventing duplicate answer fetches from the server.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
2025-12-14 14:28:57 +01:00
parent e48b3bb17a
commit b3b1751f63

View File

@@ -645,6 +645,12 @@ export class Rondevu extends EventEmitter {
try { try {
const result = await this.api.poll(this.lastPollTimestamp) const result = await this.api.poll(this.lastPollTimestamp)
// Update timestamp FIRST to prevent re-fetching same answers if processing fails
if (result.answers.length > 0) {
const maxAnswerTimestamp = Math.max(...result.answers.map(a => a.answeredAt))
this.lastPollTimestamp = Math.max(this.lastPollTimestamp, maxAnswerTimestamp)
}
// Process answers // Process answers
for (const answer of result.answers) { for (const answer of result.answers) {
const activeOffer = this.activeOffers.get(answer.offerId) const activeOffer = this.activeOffers.get(answer.offerId)
@@ -660,7 +666,6 @@ export class Rondevu extends EventEmitter {
sdp: answer.sdp sdp: answer.sdp
}) })
this.lastPollTimestamp = answer.answeredAt
this.emit('offer:answered', answer.offerId, answer.answererId) this.emit('offer:answered', answer.offerId, answer.answererId)
// Create replacement offer // Create replacement offer
@@ -668,7 +673,8 @@ export class Rondevu extends EventEmitter {
} catch (err) { } catch (err) {
// If setRemoteDescription fails, reset the answered flag // If setRemoteDescription fails, reset the answered flag
activeOffer.answered = false activeOffer.answered = false
throw err this.debug(`Failed to set remote description for offer ${answer.offerId}:`, err)
// Don't throw - continue processing other answers
} }
} }
} }