Skip to content

Conversation

@uds5501
Copy link
Contributor

@uds5501 uds5501 commented Jul 10, 2019

Fixes #2893

Server PR : fossasia/open-event-server#6163

Short description of what this resolves:

The PR implements the utlizes rate limited end point on the server side to send order confirmation for completed and placed tickets.

Changes proposed in this pull request:

  • Use payloads and display appropriate error messages

Checklist

  • I have read the Contribution & Best practices Guide.
  • My branch is up-to-date with the Upstream development branch.
  • The acceptance, integration, unit tests and linter pass locally with my changes
  • I have added tests that prove my fix is effective or that my feature works
  • I have added necessary documentation (if appropriate)

Copy link
Member

@niranjan94 niranjan94 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@uds5501 I have told this before. Do not create frontend PRs without the server code being merged in. When something depends on the server APIs, it is not possible to test the frontend code until server is merged in.

}
};
let resend = await this.loader.post('orders/resend-email', payload);
if (resend.status) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment regarding this added on the server PR. fossasia/open-event-server#6163 (comment)

@niranjan94 niranjan94 closed this Jul 10, 2019
@niranjan94
Copy link
Member

Re-open after server PR is merged

@uds5501 uds5501 requested a review from kushthedude July 13, 2019 09:05
kushthedude
kushthedude previously approved these changes Jul 13, 2019
}
};
let resendEmail = await this.loader.post('orders/resend-email', payload);
if (resendEmail.status) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@uds5501 update this to the correct error handling. If this.loader.post succeeds it should be considered a success. Any error should be in the catch block

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@niranjan94 Did it!

await this.loader.post('orders/resend-email', payload);
this.notify.success(this.l10n.t('Email confirmation has been sent to attendees successfully'));
} catch (error) {
this.notify.error(this.l10n.t('An unexpected error occurred.'));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What was the error ? Could we display something better ? Like for example, if it was a ratelimitting error, show that it was due to it. Else show whatever the actual error sent by the backend is.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@niranjan94 I have changed error handling, is it any better?

@uds5501 uds5501 force-pushed the resend-route-action branch from dfa01da to f8c6ac4 Compare July 13, 2019 17:28
this.notify.success(this.l10n.t('Email confirmation has been sent to attendees successfully'));
} catch (error) {
console.log(error);
const errorMessage = error.message || error.errors[0].detail;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about the case where the rate limiting kicks in ? What is the error message sent by the server ? Does it come in here correctly ?

Copy link
Contributor Author

@uds5501 uds5501 Jul 13, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@niranjan94 When rate limit kicks in, it's handled by error.message. If it's other trivial error like sending confirmation for cancelled orders, it's handled by error.errors[0].detail. Otherwise the else condition.

The rate limiting error sent is : TOO MANY REQUESTS.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@uds5501 for rate limiting the server would be sending a 429 if I'm right. When that comes, please show a proper and a more human-friendly error message

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, with translations

this.notify.success(this.l10n.t('Email confirmation has been sent to attendees successfully'));
} catch (error) {
console.log(error);
const errorMessage = error.message || error.errors[0].detail;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Give first priority to error.errors[0].detail. Also, what if server is sending multiple errors. You should not hard code to display only the first.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@niranjan94 Understood

@uds5501 uds5501 force-pushed the resend-route-action branch from f8c6ac4 to 427011a Compare July 13, 2019 17:59
@uds5501 uds5501 requested review from abhinavk96 and niranjan94 July 14, 2019 03:20
@uds5501 uds5501 force-pushed the resend-route-action branch from 427011a to af928c0 Compare July 16, 2019 06:45
await this.loader.post('orders/resend-email', payload);
this.notify.success(this.l10n.t('Email confirmation has been sent to attendees successfully'));
} catch (error) {
if (error.message === 'TOO MANY REQUESTS') {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@niranjan94 @shreyanshdwivedi @CosmicCoder96 Will this workaround be okay?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@uds5501 this is very wrong. You must use the status code.

Modify the loader service to ensure the original response is sent as the error along with the message that is being currently sent there

https://github.com/fossasia/open-event-frontend/blob/development/app/services/loader.js#L100

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@niranjan94 Understood.

await this.loader.post('orders/resend-email', payload);
this.notify.success(this.l10n.t('Email confirmation has been sent to attendees successfully'));
} catch (error) {
if (error.message === 'TOO MANY REQUESTS') {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@uds5501 this is very wrong. You must use the status code.

Modify the loader service to ensure the original response is sent as the error along with the message that is being currently sent there

https://github.com/fossasia/open-event-frontend/blob/development/app/services/loader.js#L100

@uds5501 uds5501 force-pushed the resend-route-action branch from af928c0 to d529408 Compare July 17, 2019 23:53
@uds5501 uds5501 requested a review from niranjan94 July 17, 2019 23:56
Copy link
Member

@niranjan94 niranjan94 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@uds5501 try not to find shortcuts. Spend some more time on fixes. See how you can make it such that its re-usable

if (parsedResponse) {
throw parsedResponse;
}
if (response.status === 429) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No. Make this a generic implementation such that status code and the original response is always passed in.

    if (!response.ok) {
      const defaultMessage = httpStatus[response.status];
      const errorResponse = pick(response, ['status', 'ok', 'statusText', 'headers', 'url']);
      errorResponse.statusText = defaultMessage;
      errorResponse.response = parsedResponse;
      errorResponse.errorMessage = isString(parsedResponse) ? parsedResponse : 
        getErrorMessage(
          response.statusText,
          defaultMessage
            ? `${response.status} - ${defaultMessage}`
            : `Could not make ${fetchOptions.type} request to ${fetchOptions.url}`
        );
      throw errorResponse;

    }

@uds5501 uds5501 force-pushed the resend-route-action branch from 7697d01 to 15a1563 Compare July 20, 2019 17:13
@uds5501 uds5501 requested a review from niranjan94 July 20, 2019 17:19
@uds5501 uds5501 force-pushed the resend-route-action branch from 15a1563 to 4e215bb Compare July 21, 2019 06:28
@uds5501
Copy link
Contributor Author

uds5501 commented Jul 24, 2019

@mrsaicharan1 @shreyanshdwivedi @CosmicCoder96 Please review this

this.notify.success(this.l10n.t('Email confirmation has been sent to attendees successfully'));
} catch (error) {
if (error.status === 429) {
this.notify.error(this.l10n.t('Only 5 resend actions are allowed in a minute'));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What if the error is something other than the two you specified.
Comparing error returned by server with the codes is not a optimisable solution its more like a workaround. @uds5501 is this the only working way for this problem ?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@kushthedude There's no context of optimality here. @uds5501 Just add an else statement for other errors & this is good to go :D

@uds5501 uds5501 force-pushed the resend-route-action branch from 4e215bb to b7463d5 Compare July 24, 2019 12:20
@uds5501 uds5501 requested a review from kushthedude July 25, 2019 10:02
mrsaicharan1
mrsaicharan1 previously approved these changes Aug 2, 2019
let payload = {};
try {
payload = {
'data': {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

 order_identifier = request.json['data']['order']
    order = safe_query(db, Order, 'identifier', order_identifier, 'identifier')
    if (has_access('is_coorganizer', event_id=order.event_id)):
        if order.status == 'completed' or order.status == 'placed':
            # fetch tickets attachment
            order_identifier = order.identifier
            key = UPLOAD_PATHS['pdf']['tickets_all'].format(identifier=order_identifier)
            ticket_path = 'generated/tickets/{}/{}/'.format(key, generate_hash(key)) + order_identifier + '.pdf'
            key = UPLOAD_PATHS['pdf']['order'].format(identifier=order_identifier)
            invoice_path = 'generated/invoices/{}/{}/'.format(key, generate_hash(key)) + order_identifier + '.pdf'

            # send email.
            send_email_to_attendees(order=order, purchaser_id=current_user.id, attachments=[ticket_path, invoice_path])
            return jsonify(status=True, message="Verification emails for order : {} has been sent succesfully".
                           format(order_identifier))
        else:
            return UnprocessableEntityError({'source': 'data/order'},
                                            "Only placed and completed orders have confirmation").respond()
    else:
        return ForbiddenError({'source': ''}, "Co-Organizer Access Required").respond()

This is the code for this end point on the server,
why is it the user field required?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

User is being used for rate limiting for users

Copy link
Contributor

@abhinavk96 abhinavk96 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That is not how commits should be, squash them use semantic naming.

@uds5501 uds5501 force-pushed the resend-route-action branch 2 times, most recently from b2157c5 to 26436bf Compare August 3, 2019 05:06
@uds5501 uds5501 force-pushed the resend-route-action branch from 26436bf to b1d83cd Compare August 3, 2019 06:10
@uds5501
Copy link
Contributor Author

uds5501 commented Aug 13, 2019

@CosmicCoder96 @mrsaicharan1 @shreyanshdwivedi @kushthedude Please review this.

@abhinavk96 abhinavk96 merged commit d6114bc into fossasia:development Aug 13, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Dummy Button under Tickets/Orders

5 participants