on master help sign in
Do wait on invite transaction confirmation
commit18d948b188c8b0bde7fa9ff8f338b2169637bb25 authorFang <git@fang.io> dateThu 6 Jun 2019, 22:24 (7 years ago) parent25f06c8
1 file changed+42−24
src/bridge/views/InvitesSend.js+42−24
src/bridge/views/InvitesSend.js+42−24
@@ -31,7 +31,8 @@ const STATUS = {
3131 CAN_SEND: 'Send invites',
3232 FUNDING: 'Funding invites',
3333 SENDING: 'Sending invites',
34− DONE: 'Done'
34+ DONE: 'Done',
35+ FAIL: 'Some failed'
3536}
3637
3738const EMAIL_STATUS = {
@@ -182,10 +183,10 @@ class InvitesSend extends React.Component {
182183 const invites = this.state.wipInvites;
183184 const web3 = this.web3;
184185
185− //TODO invite status isn't changing... why?
186+ //TODO invite status isn't changing/re-rendering... why?
186187 this.setState({
187188 status: STATUS.FUNDING,
188− invites: invites.map(i => { return {email: i.email, hasReceived: i.hasReceived, status: Nothing()}; })
189+ invites: invites.map(i => { return {...i, status: Nothing()}; })
189190 });
190191
191192 const tankWasUsed = await tank.ensureFundsFor(
@@ -197,28 +198,34 @@ class InvitesSend extends React.Component {
197198
198199 this.setState({ status: STATUS.SENDING });
199200
201+ //TODO nasty loop, probably move into lib... but so many callbacks!
202+ let promises = [];
200203 for (let i = 0; i < invites.length; i++) {
201204 const invite = invites[i];
202205
203− // send transaction, informing the user of failure
204− const txHash = await sendSignedTransaction(
205− web3, Just(invite.signedTx), tankWasUsed, ()=>{}
206− ).catch(err => {
206+ // send transaction. if it fails, inform the user and skip to next
207+ let txHash;
208+ try {
209+ txHash = await sendSignedTransaction(
210+ web3, Just(invite.signedTx), tankWasUsed, ()=>{}
211+ );
212+ } catch(err) {
207213 console.error('invite tx sending failed', err);
208214 this.addError('Invite transaction not sent for ' + invite.email);
209215 this.setEmailStatus(i, EMAIL_STATUS.FAIL);
210− });
216+ continue;
217+ };
211218
212219 // ask the email sender to send this. we can do this prior to tx confirm,
213220 // because the sender service waits for confirm & success for us.
214− const mailSuccess = await sendMail(
215− invite.email, invite.ticket, invite.rawTx
216− );
217− //TODO but this doesn't catch sender-side failures... we may
218− // just need really good monitoring for that...
219− if (mailSuccess) {
221+ // if this fails, inform the user and skip to next
222+ try {
223+ const mailSuccess = await sendMail(
224+ invite.email, invite.ticket, invite.rawTx
225+ );
226+ if (!mailSuccess) throw new Error();
220227 this.setEmailStatus(i, EMAIL_STATUS.DONE);
221− } else {
228+ } catch(e) {
222229 console.log('email send failed');
223230 //NOTE this assumes that the transaction succeeds, but we don't know
224231 // that for a fact yet...
@@ -227,21 +234,32 @@ class InvitesSend extends React.Component {
227234 '. Please give them this ticket: ' + invite.ticket
228235 );
229236 this.setEmailStatus(i, EMAIL_STATUS.FAIL);
237+ continue;
230238 }
231239
232240 // update status on transaction confirm, but don't block on it
233− waitForTransactionConfirm(web3, txHash)
234− .then(async success => {
235− if (!success) {
236− console.log('invite tx rejected');
237− this.addError('Invite transaction failed for ' + invite.email);
238− this.setEmailStatus(i, EMAIL_STATUS.FAIL);
239− }
240− });
241+ promises.push(
242+ waitForTransactionConfirm(web3, txHash)
243+ .then(success => {
244+ if (success) {
245+ this.setEmailStatus(i, EMAIL_STATUS.DONE);
246+ } else {
247+ console.log('invite tx rejected');
248+ this.addError('Invite transaction failed for ' + invite.email);
249+ this.setEmailStatus(i, EMAIL_STATUS.FAIL);
250+ }
251+ return success;
252+ })
253+ );
241254
242255 }
243256
244− this.setState({ status: STATUS.DONE });
257+ const txStatus = await Promise.all(promises);
258+ if (txStatus.every(e => e)) {
259+ this.setState({ status: STATUS.DONE });
260+ } else {
261+ this.setState({ status: STATUS.FAIL });
262+ }
245263 }
246264
247265 setEmailStatus(i, status) {