Fix duplicate answer processing regression

The activeOffer.answered flag was being set AFTER the async
setRemoteDescription() call, creating a race condition window
where the same answer could be processed multiple times.

Root cause:
- Check `!activeOffer.answered` happens
- setRemoteDescription() starts (async operation)
- Before it completes, another check could happen
- Same answer gets processed twice → "stable" state error

Fix:
- Set activeOffer.answered = true BEFORE setRemoteDescription
- Add try/catch to reset flag if setRemoteDescription fails
- This prevents duplicate processing while allowing retries on error

This regression was introduced when the answered flag assignment
was not moved along with other polling logic changes.

Fixes: #6 regression

🤖 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:19:34 +01:00
parent fcd0f8ead0
commit 8f7e15e633

View File

@@ -651,17 +651,25 @@ export class Rondevu extends EventEmitter {
if (activeOffer && !activeOffer.answered) {
this.debug(`Received answer for offer ${answer.offerId}`)
await activeOffer.pc.setRemoteDescription({
type: 'answer',
sdp: answer.sdp
})
// Mark as answered BEFORE setRemoteDescription to prevent race condition
activeOffer.answered = true
this.lastPollTimestamp = answer.answeredAt
this.emit('offer:answered', answer.offerId, answer.answererId)
// Create replacement offer
this.fillOffers()
try {
await activeOffer.pc.setRemoteDescription({
type: 'answer',
sdp: answer.sdp
})
this.lastPollTimestamp = answer.answeredAt
this.emit('offer:answered', answer.offerId, answer.answererId)
// Create replacement offer
this.fillOffers()
} catch (err) {
// If setRemoteDescription fails, reset the answered flag
activeOffer.answered = false
throw err
}
}
}