on master help sign in
Do wait on invite transaction confirmation
18d948bFang
src/bridge/views/InvitesSend.js+42−24
@@ -31,7 +31,8 @@ const STATUS = {
31 CAN_SEND: 'Send invites',
31 CAN_SEND: 'Send invites',
32 FUNDING: 'Funding invites',
32 FUNDING: 'Funding invites',
33 SENDING: 'Sending invites',
33 SENDING: 'Sending invites',
34− DONE: 'Done'
34+ DONE: 'Done',
35+ FAIL: 'Some failed'
35}
36}
36
37
37const EMAIL_STATUS = {
38const EMAIL_STATUS = {
@@ -182,10 +183,10 @@ class InvitesSend extends React.Component {
182 const invites = this.state.wipInvites;
183 const invites = this.state.wipInvites;
183 const web3 = this.web3;
184 const web3 = this.web3;
184
185
185− //TODO invite status isn't changing... why?
186+ //TODO invite status isn't changing/re-rendering... why?
186 this.setState({
187 this.setState({
187 status: STATUS.FUNDING,
188 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()}; })
189 });
190 });
190
191
191 const tankWasUsed = await tank.ensureFundsFor(
192 const tankWasUsed = await tank.ensureFundsFor(
@@ -197,28 +198,34 @@ class InvitesSend extends React.Component {
197
198
198 this.setState({ status: STATUS.SENDING });
199 this.setState({ status: STATUS.SENDING });
199
200
201+ //TODO nasty loop, probably move into lib... but so many callbacks!
202+ let promises = [];
200 for (let i = 0; i < invites.length; i++) {
203 for (let i = 0; i < invites.length; i++) {
201 const invite = invites[i];
204 const invite = invites[i];
202
205
203− // send transaction, informing the user of failure
206+ // send transaction. if it fails, inform the user and skip to next
207+ let txHash;
208+ try {
204− const txHash = await sendSignedTransaction(
209+ txHash = await sendSignedTransaction(
205− web3, Just(invite.signedTx), tankWasUsed, ()=>{}
210+ web3, Just(invite.signedTx), tankWasUsed, ()=>{}
211+ );
206− ).catch(err => {
212+ } catch(err) {
207 console.error('invite tx sending failed', err);
213 console.error('invite tx sending failed', err);
208 this.addError('Invite transaction not sent for ' + invite.email);
214 this.addError('Invite transaction not sent for ' + invite.email);
209 this.setEmailStatus(i, EMAIL_STATUS.FAIL);
215 this.setEmailStatus(i, EMAIL_STATUS.FAIL);
216+ continue;
210− });
217+ };
211
218
212 // ask the email sender to send this. we can do this prior to tx confirm,
219 // ask the email sender to send this. we can do this prior to tx confirm,
213 // because the sender service waits for confirm & success for us.
220 // because the sender service waits for confirm & success for us.
221+ // if this fails, inform the user and skip to next
222+ try {
214− const mailSuccess = await sendMail(
223+ const mailSuccess = await sendMail(
215− invite.email, invite.ticket, invite.rawTx
224+ invite.email, invite.ticket, invite.rawTx
216− );
225+ );
217− //TODO but this doesn't catch sender-side failures... we may
226+ if (!mailSuccess) throw new Error();
218− // just need really good monitoring for that...
219− if (mailSuccess) {
220 this.setEmailStatus(i, EMAIL_STATUS.DONE);
227 this.setEmailStatus(i, EMAIL_STATUS.DONE);
221− } else {
228+ } catch(e) {
222 console.log('email send failed');
229 console.log('email send failed');
223 //NOTE this assumes that the transaction succeeds, but we don't know
230 //NOTE this assumes that the transaction succeeds, but we don't know
224 // that for a fact yet...
231 // that for a fact yet...
@@ -227,21 +234,32 @@ class InvitesSend extends React.Component {
227 '. Please give them this ticket: ' + invite.ticket
234 '. Please give them this ticket: ' + invite.ticket
228 );
235 );
229 this.setEmailStatus(i, EMAIL_STATUS.FAIL);
236 this.setEmailStatus(i, EMAIL_STATUS.FAIL);
237+ continue;
230 }
238 }
231
239
232 // update status on transaction confirm, but don't block on it
240 // update status on transaction confirm, but don't block on it
241+ promises.push(
233− waitForTransactionConfirm(web3, txHash)
242+ waitForTransactionConfirm(web3, txHash)
234− .then(async success => {
243+ .then(success => {
235− if (!success) {
244+ if (success) {
245+ this.setEmailStatus(i, EMAIL_STATUS.DONE);
246+ } else {
236− console.log('invite tx rejected');
247+ console.log('invite tx rejected');
237− this.addError('Invite transaction failed for ' + invite.email);
248+ this.addError('Invite transaction failed for ' + invite.email);
238− this.setEmailStatus(i, EMAIL_STATUS.FAIL);
249+ this.setEmailStatus(i, EMAIL_STATUS.FAIL);
250+ }
251+ return success;
239− }
252+ })
240− });
253+ );
241
254
242 }
255 }
243
256
257+ const txStatus = await Promise.all(promises);
258+ if (txStatus.every(e => e)) {
244− this.setState({ status: STATUS.DONE });
259+ this.setState({ status: STATUS.DONE });
260+ } else {
261+ this.setState({ status: STATUS.FAIL });
262+ }
245 }
263 }
246
264
247 setEmailStatus(i, status) {
265 setEmailStatus(i, status) {